diff --git a/README.md b/README.md index 49dcbe5..07674af 100644 --- a/README.md +++ b/README.md @@ -70,11 +70,11 @@ glider -config CONFIGPATH -listen :8080 -verbose ## Usage ```bash -glider v0.3 usage: +glider v0.3.1 usage: -checkduration int proxy check duration(seconds) (default 30) -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 file path -forward value @@ -134,13 +134,13 @@ Examples: 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. - 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. - 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. - 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. 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 # 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) 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 # check address (to check whether a host is reachable via forward proxy) -checkhost=www.apple.com:443 +checkhost=www.apple.com:8443 # check duration checkduration=30 @@ -199,10 +199,10 @@ Rule file, **same as the config file but specify forwarders based on destination ```bash # YOU CAN USE ALL KEYS IN THE GLOBAL CONFIG FILE EXCEPT "listen", "rulefile" 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 strategy=rr -checkwebsite=www.apple.com:443 +checkwebsite=www.apple.com checkduration=30 # YOU CAN SPECIFY DESTINATIONS TO USE THE ABOVE FORWARDERS diff --git a/examples/multiple_forwarders/glider.conf b/examples/multiple_forwarders/glider.conf index 370d931..91252f9 100644 --- a/examples/multiple_forwarders/glider.conf +++ b/examples/multiple_forwarders/glider.conf @@ -14,8 +14,8 @@ strategy=rr # Used to connect via forwarders, if the host is unreachable, the forwarder # will be set to disabled. -# MUST BE A HTTP or HTTPS WEBSITE HOST ADDRESS -checkwebsite=www.apple.com:443 +# MUST be a HTTP website server address, format: HOST[:PORT]. HTTPS NOT SUPPORTED. +checkwebsite=www.apple.com # check duration(seconds) checkduration=30 diff --git a/examples/rule_default_direct/office.rule b/examples/rule_default_direct/office.rule index f1db4e7..5b1330d 100644 --- a/examples/rule_default_direct/office.rule +++ b/examples/rule_default_direct/office.rule @@ -8,7 +8,7 @@ forward=http://1.1.1.1:8080 # High Availability mode: ha strategy=rr -checkwebsite=www.apple.com:443 +checkwebsite=www.apple.com checkduration=30 diff --git a/examples/rule_default_forwarder/glider.conf b/examples/rule_default_forwarder/glider.conf index a0e98a1..e98b807 100644 --- a/examples/rule_default_forwarder/glider.conf +++ b/examples/rule_default_forwarder/glider.conf @@ -13,7 +13,7 @@ forward=http://1.1.1.1:8080 # High Availability mode: ha strategy=rr -checkwebsite=www.apple.com:443 +checkwebsite=www.apple.com checkduration=30 diff --git a/examples/rule_multiple_rule_files/home.rule b/examples/rule_multiple_rule_files/home.rule index 9babf93..06759cb 100644 --- a/examples/rule_multiple_rule_files/home.rule +++ b/examples/rule_multiple_rule_files/home.rule @@ -10,7 +10,7 @@ forward=http://forwarder5:8080,socks6://forwarder3:1080 # High Availability mode: ha strategy=rr -checkwebsite=www.apple.com:443 +checkwebsite=www.apple.com checkduration=30 diff --git a/examples/rule_multiple_rule_files/office.rule b/examples/rule_multiple_rule_files/office.rule index bf2db09..3ff311f 100644 --- a/examples/rule_multiple_rule_files/office.rule +++ b/examples/rule_multiple_rule_files/office.rule @@ -2,7 +2,7 @@ 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 @@ -10,7 +10,7 @@ forward=http://forwarder2:8080,socks5://forwarder3:1080 # High Availability mode: ha strategy=rr -checkwebsite=www.apple.com:443 +checkwebsite=www.apple.com checkduration=30 diff --git a/glider.conf.example b/glider.conf.example index 8656872..0d62abb 100644 --- a/glider.conf.example +++ b/glider.conf.example @@ -62,7 +62,7 @@ listen=socks5://:1080 #forward=socks5://192.168.1.10:1080 # 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 # 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 # will be set to disabled. -# MUST BE A HTTP or HTTPS WEBSITE HOST ADDRESS -checkwebsite=www.apple.com:443 +# MUST be a HTTP website server address, format: HOST[:PORT]. HTTPS NOT SUPPORTED. +checkwebsite=www.apple.com # check duration(seconds) checkduration=30 diff --git a/main.go b/main.go index d94002f..8e17b77 100644 --- a/main.go +++ b/main.go @@ -12,7 +12,7 @@ import ( ) // VERSION . -const VERSION = "0.3" +const VERSION = "0.3.1" var conf struct { 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, " -listen on :8080 as a http proxy server, forward all requests via socks5 server.\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, "\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, "\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, "\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.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.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]") diff --git a/office.rule.example b/office.rule.example index cb4b97a..2635c84 100644 --- a/office.rule.example +++ b/office.rule.example @@ -7,12 +7,12 @@ # ---------- # Forwarders, we can setup multiple forwarders. 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 strategy=rr -checkwebsite=www.apple.com:443 +checkwebsite=www.apple.com checkduration=30 # DESTINATIONS diff --git a/proxy.go b/proxy.go index 17952f7..ff66ce0 100644 --- a/proxy.go +++ b/proxy.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "errors" "io" "net" @@ -112,35 +113,45 @@ func ProxyFromURL(s string, forwarder Proxy) (Proxy, error) { } // Check proxy -func check(p Proxy, target string, duration int) { - firstTime := true - buf := make([]byte, 8) +func check(p Proxy, webhost string, duration int) { + retry := 1 + buf := make([]byte, 4) + + if strings.IndexByte(webhost, ':') == -1 { + webhost = webhost + ":80" + } for { - if !firstTime { - time.Sleep(time.Duration(duration) * time.Second) + time.Sleep(time.Duration(duration) * time.Second * time.Duration(retry>>1)) + retry <<= 1 + + if retry > 16 { + retry = 16 } - firstTime = false startTime := time.Now() - c, err := p.Dial("tcp", target) + c, err := p.Dial("tcp", webhost) if err != nil { 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 } c.Write([]byte("GET / HTTP/1.0")) c.Write([]byte("\r\n\r\n")) - _, err = c.Read(buf) - if err != nil && err != io.EOF { + _, err = io.ReadFull(c, buf) + if err != nil { p.SetEnable(false) - logf("proxy-check %s -> %s, set to DISABLED. error: %s", p.Addr(), target, err) - } else { + logf("proxy-check %s -> %s, set to DISABLED. error in read: %s", p.Addr(), webhost, err) + } else if bytes.Equal([]byte("HTTP"), buf) { p.SetEnable(true) + retry = 2 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() diff --git a/rule.go b/rule.go index a71cfab..060a70e 100644 --- a/rule.go +++ b/rule.go @@ -31,7 +31,7 @@ func newRuleProxyFromFile(ruleFile string) (*ruleForwarder, error) { 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.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.Var(&p.Domain, "domain", "domain")