mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
strategy: added new option checkfailedonly #138
This commit is contained in:
parent
149824cc20
commit
0b0611a0dc
1
conf.go
1
conf.go
@ -43,6 +43,7 @@ func confInit() {
|
|||||||
flag.StringVar(&conf.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
|
flag.StringVar(&conf.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
|
||||||
flag.IntVar(&conf.StrategyConfig.CheckInterval, "checkinterval", 30, "proxy check interval(seconds)")
|
flag.IntVar(&conf.StrategyConfig.CheckInterval, "checkinterval", 30, "proxy check interval(seconds)")
|
||||||
flag.IntVar(&conf.StrategyConfig.CheckTimeout, "checktimeout", 10, "proxy check timeout(seconds)")
|
flag.IntVar(&conf.StrategyConfig.CheckTimeout, "checktimeout", 10, "proxy check timeout(seconds)")
|
||||||
|
flag.BoolVar(&conf.StrategyConfig.CheckFailedOnly, "checkfailedonly", false, "check failed fowarder only")
|
||||||
flag.IntVar(&conf.StrategyConfig.MaxFailures, "maxfailures", 3, "max failures to change forwarder status to disabled")
|
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.StringVar(&conf.StrategyConfig.IntFace, "interface", "", "source ip or source interface")
|
||||||
|
|
||||||
|
4
go.mod
4
go.mod
@ -10,9 +10,9 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/tjfoc/gmsm v1.3.0 // indirect
|
github.com/tjfoc/gmsm v1.3.0 // indirect
|
||||||
github.com/xtaci/kcp-go/v5 v5.5.12
|
github.com/xtaci/kcp-go/v5 v5.5.12
|
||||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904
|
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
|
||||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect
|
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
// Replace dependency modules with local developing copy
|
// Replace dependency modules with local developing copy
|
||||||
|
8
go.sum
8
go.sum
@ -58,8 +58,8 @@ golang.org/x/crypto v0.0.0-20191010185427-af544f31c8ac/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
|
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 h1:IhZPbxNd1UjBCaD5AfpSSbJTRlp+ZSuyuH5uoksNS04=
|
||||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@ -73,8 +73,8 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
|
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
||||||
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -21,6 +21,7 @@ type Config struct {
|
|||||||
CheckWebSite string
|
CheckWebSite string
|
||||||
CheckInterval int
|
CheckInterval int
|
||||||
CheckTimeout int
|
CheckTimeout int
|
||||||
|
CheckFailedOnly bool
|
||||||
MaxFailures int
|
MaxFailures int
|
||||||
IntFace string
|
IntFace string
|
||||||
}
|
}
|
||||||
@ -185,64 +186,94 @@ func (p *Proxy) Check() {
|
|||||||
// no need to check when there's only 1 forwarder
|
// no need to check when there's only 1 forwarder
|
||||||
if len(p.fwdrs) > 1 {
|
if len(p.fwdrs) > 1 {
|
||||||
for i := 0; i < len(p.fwdrs); i++ {
|
for i := 0; i < len(p.fwdrs); i++ {
|
||||||
go p.check(i)
|
go p.check(p.fwdrs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) check(i int) {
|
func (p *Proxy) check(f *Forwarder) {
|
||||||
f := p.fwdrs[i]
|
wait := uint8(0)
|
||||||
retry := 1
|
|
||||||
buf := make([]byte, 4)
|
buf := make([]byte, 4)
|
||||||
|
intval := time.Duration(p.config.CheckInterval) * time.Second
|
||||||
|
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Duration(p.config.CheckInterval) * time.Second * time.Duration(retry>>1))
|
time.Sleep(intval * time.Duration(wait))
|
||||||
|
|
||||||
// check all forwarders at least one time
|
// check all forwarders at least one time
|
||||||
if retry > 1 && f.Priority() < p.Priority() {
|
if wait > 0 && (f.Priority() < p.Priority()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
retry <<= 1
|
if f.Enabled() && p.config.CheckFailedOnly {
|
||||||
if retry > 16 {
|
continue
|
||||||
retry = 16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if checkWebSite(f, p.config.CheckWebSite, time.Duration(p.config.CheckTimeout)*time.Second, buf) {
|
||||||
|
wait = 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if wait == 0 {
|
||||||
|
wait = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait *= 2
|
||||||
|
if wait > 16 {
|
||||||
|
wait = 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []byte) bool {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
rc, err := f.Dial("tcp", p.config.CheckWebSite)
|
|
||||||
if err != nil {
|
|
||||||
f.Disable()
|
|
||||||
log.F("[check] %s(%d) -> %s, DISABLED. error in dial: %s", f.Addr(), f.Priority(), p.config.CheckWebSite, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
rc.Write([]byte("GET / HTTP/1.0\r\n\r\n"))
|
rc, err := fwdr.Dial("tcp", website)
|
||||||
|
if err != nil {
|
||||||
|
fwdr.Disable()
|
||||||
|
log.F("[check] %s(%d) -> %s, DISABLED. error in dial: %s", fwdr.Addr(), fwdr.Priority(),
|
||||||
|
website, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer rc.Close()
|
||||||
|
|
||||||
|
_, err = rc.Write([]byte("GET / HTTP/1.0\r\n\r\n"))
|
||||||
|
if err != nil {
|
||||||
|
fwdr.Disable()
|
||||||
|
log.F("[check] %s(%d) -> %s, DISABLED. error in write: %s", fwdr.Addr(), fwdr.Priority(),
|
||||||
|
website, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
_, err = io.ReadFull(rc, buf)
|
_, err = io.ReadFull(rc, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, DISABLED. error in read: %s", f.Addr(), f.Priority(), p.config.CheckWebSite, err)
|
log.F("[check] %s(%d) -> %s, DISABLED. error in read: %s", fwdr.Addr(), fwdr.Priority(),
|
||||||
} else if bytes.Equal([]byte("HTTP"), buf) {
|
website, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal([]byte("HTTP"), buf) {
|
||||||
|
fwdr.Disable()
|
||||||
|
log.F("[check] %s(%d) -> %s, DISABLED. server response: %s", fwdr.Addr(), fwdr.Priority(),
|
||||||
|
website, buf)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
readTime := time.Since(startTime)
|
readTime := time.Since(startTime)
|
||||||
f.SetLatency(int64(readTime))
|
fwdr.SetLatency(int64(readTime))
|
||||||
|
|
||||||
if readTime > time.Duration(p.config.CheckTimeout)*time.Second {
|
if readTime > timeout {
|
||||||
f.Disable()
|
fwdr.Disable()
|
||||||
log.F("[check] %s(%d) -> %s, DISABLED. check timeout: %s", f.Addr(), f.Priority(), p.config.CheckWebSite, readTime)
|
log.F("[check] %s(%d) -> %s, DISABLED. check timeout: %s", fwdr.Addr(), fwdr.Priority(),
|
||||||
} else {
|
website, readTime)
|
||||||
retry = 2
|
return false
|
||||||
f.Enable()
|
|
||||||
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", f.Addr(), f.Priority(), p.config.CheckWebSite, readTime)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
fwdr.Enable()
|
||||||
f.Disable()
|
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", fwdr.Addr(), fwdr.Priority(),
|
||||||
log.F("[check] %s(%d) -> %s, DISABLED. server response: %s", f.Addr(), f.Priority(), p.config.CheckWebSite, buf)
|
website, readTime)
|
||||||
}
|
|
||||||
|
|
||||||
rc.Close()
|
return true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round Robin
|
// Round Robin
|
||||||
|
Loading…
Reference in New Issue
Block a user