proxy chek: 1. improve check method: send a http get request and check the response, if the first 4 byte is "HTTP" then the proxy is avaliable. 2. if a proxy is disabled, increase the check duration. 3. update related docs.

This commit is contained in:
nadoo 2017-07-31 13:42:11 +08:00
parent 8527d48190
commit a06d56cce0
11 changed files with 51 additions and 40 deletions

View File

@ -70,11 +70,11 @@ glider -config CONFIGPATH -listen :8080 -verbose
## Usage ## Usage
```bash ```bash
glider v0.3 usage: glider v0.3.1 usage:
-checkduration int -checkduration int
proxy check duration(seconds) (default 30) proxy check duration(seconds) (default 30)
-checkwebsite string -checkwebsite string
proxy check WEBSITE address (default "www.apple.com:443") proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80 (default "www.apple.com")
-config string -config string
config file path config file path
-forward value -forward value
@ -134,13 +134,13 @@ Examples:
glider -listen http://:8080 -forward socks5://127.0.0.1:1080 glider -listen http://:8080 -forward socks5://127.0.0.1:1080
-listen on :8080 as a http proxy server, forward all requests via socks5 server. -listen on :8080 as a http proxy server, forward all requests via socks5 server.
glider -listen redir://:1081 -forward ss://method:pass@1.1.1.1:443 glider -listen redir://:1081 -forward ss://method:pass@1.1.1.1:8443
-listen on :1081 as a transparent redirect server, forward all requests via remote ss server. -listen on :1081 as a transparent redirect server, forward all requests via remote ss server.
glider -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:443 glider -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:8443
-listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server. -listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server.
glider -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:443 glider -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:8443
-listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server. -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server.
glider -listen redir://:1081 -listen dnstun://:53=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2 glider -listen redir://:1081 -listen dnstun://:53=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2
@ -172,7 +172,7 @@ listen=dnstun://:53=8.8.8.8:53
forward=socks5://192.168.1.10:1080 forward=socks5://192.168.1.10:1080
# upstream forward proxy # upstream forward proxy
forward=ss://method:pass@1.1.1.1:443 forward=ss://method:pass@1.1.1.1:8443
# upstream forward proxy (forward chain) # upstream forward proxy (forward chain)
forward=http://1.1.1.1:8080,socks5://2.2.2.2:1080 forward=http://1.1.1.1:8080,socks5://2.2.2.2:1080
@ -181,7 +181,7 @@ forward=http://1.1.1.1:8080,socks5://2.2.2.2:1080
strategy=rr strategy=rr
# check address (to check whether a host is reachable via forward proxy) # check address (to check whether a host is reachable via forward proxy)
checkhost=www.apple.com:443 checkhost=www.apple.com:8443
# check duration # check duration
checkduration=30 checkduration=30
@ -199,10 +199,10 @@ Rule file, **same as the config file but specify forwarders based on destination
```bash ```bash
# YOU CAN USE ALL KEYS IN THE GLOBAL CONFIG FILE EXCEPT "listen", "rulefile" # YOU CAN USE ALL KEYS IN THE GLOBAL CONFIG FILE EXCEPT "listen", "rulefile"
forward=socks5://192.168.1.10:1080 forward=socks5://192.168.1.10:1080
forward=ss://method:pass@1.1.1.1:443 forward=ss://method:pass@1.1.1.1:8443
forward=http://192.168.2.1:8080,socks5://192.168.2.2:1080 forward=http://192.168.2.1:8080,socks5://192.168.2.2:1080
strategy=rr strategy=rr
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
checkduration=30 checkduration=30
# YOU CAN SPECIFY DESTINATIONS TO USE THE ABOVE FORWARDERS # YOU CAN SPECIFY DESTINATIONS TO USE THE ABOVE FORWARDERS

View File

@ -14,8 +14,8 @@ strategy=rr
# Used to connect via forwarders, if the host is unreachable, the forwarder # Used to connect via forwarders, if the host is unreachable, the forwarder
# will be set to disabled. # will be set to disabled.
# MUST BE A HTTP or HTTPS WEBSITE HOST ADDRESS # MUST be a HTTP website server address, format: HOST[:PORT]. HTTPS NOT SUPPORTED.
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
# check duration(seconds) # check duration(seconds)
checkduration=30 checkduration=30

View File

@ -8,7 +8,7 @@ forward=http://1.1.1.1:8080
# High Availability mode: ha # High Availability mode: ha
strategy=rr strategy=rr
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
checkduration=30 checkduration=30

View File

@ -13,7 +13,7 @@ forward=http://1.1.1.1:8080
# High Availability mode: ha # High Availability mode: ha
strategy=rr strategy=rr
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
checkduration=30 checkduration=30

View File

@ -10,7 +10,7 @@ forward=http://forwarder5:8080,socks6://forwarder3:1080
# High Availability mode: ha # High Availability mode: ha
strategy=rr strategy=rr
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
checkduration=30 checkduration=30

View File

@ -2,7 +2,7 @@
forward=http://forwarder1:8080 forward=http://forwarder1:8080
# first connect forwarder1 then forwarder2 then internet # first connect forwarder2 then forwarder3 then internet
forward=http://forwarder2:8080,socks5://forwarder3:1080 forward=http://forwarder2:8080,socks5://forwarder3:1080
@ -10,7 +10,7 @@ forward=http://forwarder2:8080,socks5://forwarder3:1080
# High Availability mode: ha # High Availability mode: ha
strategy=rr strategy=rr
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
checkduration=30 checkduration=30

View File

@ -62,7 +62,7 @@ listen=socks5://:1080
#forward=socks5://192.168.1.10:1080 #forward=socks5://192.168.1.10:1080
# SS proxy as forwarder # SS proxy as forwarder
# forward=ss://method:pass@1.1.1.1:443 # forward=ss://method:pass@1.1.1.1:8443
# http proxy as forwarder # http proxy as forwarder
# forward=http://1.1.1.1:8080 # forward=http://1.1.1.1:8080
@ -89,8 +89,8 @@ strategy=rr
# Used to connect via forwarders, if the host is unreachable, the forwarder # Used to connect via forwarders, if the host is unreachable, the forwarder
# will be set to disabled. # will be set to disabled.
# MUST BE A HTTP or HTTPS WEBSITE HOST ADDRESS # MUST be a HTTP website server address, format: HOST[:PORT]. HTTPS NOT SUPPORTED.
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
# check duration(seconds) # check duration(seconds)
checkduration=30 checkduration=30

10
main.go
View File

@ -12,7 +12,7 @@ import (
) )
// VERSION . // VERSION .
const VERSION = "0.3" const VERSION = "0.3.1"
var conf struct { var conf struct {
Verbose bool Verbose bool
@ -91,13 +91,13 @@ func usage() {
fmt.Fprintf(os.Stderr, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n") fmt.Fprintf(os.Stderr, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n")
fmt.Fprintf(os.Stderr, " -listen on :8080 as a http proxy server, forward all requests via socks5 server.\n") fmt.Fprintf(os.Stderr, " -listen on :8080 as a http proxy server, forward all requests via socks5 server.\n")
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen redir://:1081 -forward ss://method:pass@1.1.1.1:443\n") fmt.Fprintf(os.Stderr, " "+app+" -listen redir://:1081 -forward ss://method:pass@1.1.1.1:8443\n")
fmt.Fprintf(os.Stderr, " -listen on :1081 as a transparent redirect server, forward all requests via remote ss server.\n") fmt.Fprintf(os.Stderr, " -listen on :1081 as a transparent redirect server, forward all requests via remote ss server.\n")
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:443\n") fmt.Fprintf(os.Stderr, " "+app+" -listen tcptun://:80=2.2.2.2:80 -forward ss://method:pass@1.1.1.1:8443\n")
fmt.Fprintf(os.Stderr, " -listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server.\n") fmt.Fprintf(os.Stderr, " -listen on :80 and forward all requests to 2.2.2.2:80 via remote ss server.\n")
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:443\n") fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:8443\n")
fmt.Fprintf(os.Stderr, " -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server.\n") fmt.Fprintf(os.Stderr, " -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server.\n")
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen redir://:1081 -listen dnstun://:53=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2\n") fmt.Fprintf(os.Stderr, " "+app+" -listen redir://:1081 -listen dnstun://:53=8.8.8.8:53 -forward ss://method:pass@server1:port1,ss://method:pass@server2:port2\n")
@ -125,7 +125,7 @@ func main() {
flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode") flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode")
flag.StringVar(&conf.Strategy, "strategy", "rr", "forward strategy, default: rr") flag.StringVar(&conf.Strategy, "strategy", "rr", "forward strategy, default: rr")
flag.StringVar(&conf.CheckWebSite, "checkwebsite", "www.apple.com:443", "proxy check WEBSITE address") flag.StringVar(&conf.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
flag.IntVar(&conf.CheckDuration, "checkduration", 30, "proxy check duration(seconds)") flag.IntVar(&conf.CheckDuration, "checkduration", 30, "proxy check duration(seconds)")
flag.Var(&conf.Listen, "listen", "listen url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT") flag.Var(&conf.Listen, "listen", "listen url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT")
flag.Var(&conf.Forward, "forward", "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]") flag.Var(&conf.Forward, "forward", "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]")

View File

@ -7,12 +7,12 @@
# ---------- # ----------
# Forwarders, we can setup multiple forwarders. # Forwarders, we can setup multiple forwarders.
forward=socks5://192.168.1.10:1080 forward=socks5://192.168.1.10:1080
forward=ss://method:pass@1.1.1.1:443 forward=ss://method:pass@1.1.1.1:8443
forward=http://192.168.2.1:8080,socks5://192.168.2.2:1080 forward=http://192.168.2.1:8080,socks5://192.168.2.2:1080
strategy=rr strategy=rr
checkwebsite=www.apple.com:443 checkwebsite=www.apple.com
checkduration=30 checkduration=30
# DESTINATIONS # DESTINATIONS

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"errors" "errors"
"io" "io"
"net" "net"
@ -112,35 +113,45 @@ func ProxyFromURL(s string, forwarder Proxy) (Proxy, error) {
} }
// Check proxy // Check proxy
func check(p Proxy, target string, duration int) { func check(p Proxy, webhost string, duration int) {
firstTime := true retry := 1
buf := make([]byte, 8) buf := make([]byte, 4)
if strings.IndexByte(webhost, ':') == -1 {
webhost = webhost + ":80"
}
for { for {
if !firstTime { time.Sleep(time.Duration(duration) * time.Second * time.Duration(retry>>1))
time.Sleep(time.Duration(duration) * time.Second) retry <<= 1
if retry > 16 {
retry = 16
} }
firstTime = false
startTime := time.Now() startTime := time.Now()
c, err := p.Dial("tcp", target) c, err := p.Dial("tcp", webhost)
if err != nil { if err != nil {
p.SetEnable(false) p.SetEnable(false)
logf("proxy-check %s -> %s, set to DISABLED. error: %s", p.Addr(), target, err) logf("proxy-check %s -> %s, set to DISABLED. error in dial: %s", p.Addr(), webhost, err)
continue continue
} }
c.Write([]byte("GET / HTTP/1.0")) c.Write([]byte("GET / HTTP/1.0"))
c.Write([]byte("\r\n\r\n")) c.Write([]byte("\r\n\r\n"))
_, err = c.Read(buf) _, err = io.ReadFull(c, buf)
if err != nil && err != io.EOF { if err != nil {
p.SetEnable(false) p.SetEnable(false)
logf("proxy-check %s -> %s, set to DISABLED. error: %s", p.Addr(), target, err) logf("proxy-check %s -> %s, set to DISABLED. error in read: %s", p.Addr(), webhost, err)
} else { } else if bytes.Equal([]byte("HTTP"), buf) {
p.SetEnable(true) p.SetEnable(true)
retry = 2
dialTime := time.Since(startTime) dialTime := time.Since(startTime)
logf("proxy-check: %s -> %s, connect time: %s", p.Addr(), target, dialTime.String()) logf("proxy-check: %s -> %s, set to ENABLED. connect time: %s", p.Addr(), webhost, dialTime.String())
} else {
p.SetEnable(false)
logf("proxy-check %s -> %s, set to DISABLED. server response: %s", p.Addr(), webhost, buf)
} }
c.Close() c.Close()

View File

@ -31,7 +31,7 @@ func newRuleProxyFromFile(ruleFile string) (*ruleForwarder, error) {
f := conflag.NewFromFile("rule", ruleFile) f := conflag.NewFromFile("rule", ruleFile)
f.Var(&p.Forward, "forward", "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]") f.Var(&p.Forward, "forward", "forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT]")
f.StringVar(&p.Strategy, "strategy", "rr", "forward strategy, default: rr") f.StringVar(&p.Strategy, "strategy", "rr", "forward strategy, default: rr")
f.StringVar(&p.CheckWebSite, "checkwebsite", "www.apple.com:443", "proxy check website address") f.StringVar(&p.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
f.IntVar(&p.CheckDuration, "checkduration", 30, "proxy check duration(seconds)") f.IntVar(&p.CheckDuration, "checkduration", 30, "proxy check duration(seconds)")
f.Var(&p.Domain, "domain", "domain") f.Var(&p.Domain, "domain", "domain")