diff --git a/README.md b/README.md index 60bdec9..e0c0b3d 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ glider 0.16.0 usage: check=tcp[://HOST:PORT]: tcp port connect check check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE] check=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE] - check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR + check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200") -checkdisabledonly check disabled fowarders only diff --git a/config.go b/config.go index a3c25df..798ca8c 100644 --- a/config.go +++ b/config.go @@ -51,7 +51,7 @@ func parseConfig() *Config { flag.StringSliceVar(&conf.Forwards, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]") flag.StringVar(&conf.Strategy.Strategy, "strategy", "rr", "forward strategy, default: rr") - flag.StringVar(&conf.Strategy.Check, "check", "http://www.msftconnecttest.com/connecttest.txt#expect=200", "check=tcp[://HOST:PORT]: tcp port connect check\ncheck=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR\ncheck=disable: disable health check") + flag.StringVar(&conf.Strategy.Check, "check", "http://www.msftconnecttest.com/connecttest.txt#expect=200", "check=tcp[://HOST:PORT]: tcp port connect check\ncheck=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL\ncheck=disable: disable health check") flag.IntVar(&conf.Strategy.CheckInterval, "checkinterval", 30, "fowarder check interval(seconds)") flag.IntVar(&conf.Strategy.CheckTimeout, "checktimeout", 10, "fowarder check timeout(seconds)") flag.IntVar(&conf.Strategy.CheckTolerance, "checktolerance", 0, "fowarder check tolerance(ms), switch only when new_latency < old_latency - tolerance, only used in lha mode") diff --git a/config/glider.conf.example b/config/glider.conf.example index a17aeed..519c117 100644 --- a/config/glider.conf.example +++ b/config/glider.conf.example @@ -195,7 +195,7 @@ maxfailures=3 # check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE] # check=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE] # e.g. check=https://www.netflix.com/title/81215567#expect=301|404 -# check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR +# check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL # check=disable: disable health check check=http://www.msftconnecttest.com/connecttest.txt#expect=200 diff --git a/go.mod b/go.mod index 9a570fd..c6859ea 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/nadoo/conflag v0.2.3 github.com/nadoo/ipset v0.4.0 github.com/xtaci/kcp-go/v5 v5.6.1 - golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce + golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 ) diff --git a/go.sum b/go.sum index adc0ff7..b2e999f 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,8 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= -golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8 h1:kACShD3qhmr/3rLmg1yXyt+N4HcwutKyPRB93s54TIU= +golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= diff --git a/rule/check.go b/rule/check.go index 7457f0c..381a633 100644 --- a/rule/check.go +++ b/rule/check.go @@ -13,12 +13,11 @@ import ( "time" "github.com/nadoo/glider/pkg/pool" - "github.com/nadoo/glider/proxy" ) // Checker is a forwarder health checker. type Checker interface { - Check(dialer proxy.Dialer) (elap time.Duration, err error) + Check(fwdr *Forwarder) (elap time.Duration, err error) } type tcpChecker struct { @@ -34,9 +33,9 @@ func newTcpChecker(addr string, timeout time.Duration) *tcpChecker { } // Check implements the Checker interface. -func (c *tcpChecker) Check(dialer proxy.Dialer) (time.Duration, error) { +func (c *tcpChecker) Check(fwdr *Forwarder) (time.Duration, error) { startTime := time.Now() - rc, err := dialer.Dial("tcp", c.addr) + rc, err := fwdr.Dial("tcp", c.addr) if err != nil { return 0, err } @@ -80,9 +79,9 @@ func newHttpChecker(addr, uri, expect string, timeout time.Duration, withTLS boo } // Check implements the Checker interface. -func (c *httpChecker) Check(dialer proxy.Dialer) (time.Duration, error) { +func (c *httpChecker) Check(fwdr *Forwarder) (time.Duration, error) { startTime := time.Now() - rc, err := dialer.Dial("tcp", c.addr) + rc, err := fwdr.Dial("tcp", c.addr) if err != nil { return 0, err } @@ -131,10 +130,11 @@ type fileChecker struct{ path string } func newFileChecker(path string) *fileChecker { return &fileChecker{path} } // Check implements the Checker interface. -func (c *fileChecker) Check(dialer proxy.Dialer) (time.Duration, error) { +func (c *fileChecker) Check(fwdr *Forwarder) (time.Duration, error) { cmd := exec.Command(c.path) cmd.Stdout = os.Stdout cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "FORWARDER_ADDR="+dialer.Addr()) + cmd.Env = append(cmd.Env, "FORWARDER_ADDR="+fwdr.Addr()) + cmd.Env = append(cmd.Env, "FORWARDER_URL="+fwdr.URL()) return 0, cmd.Run() } diff --git a/rule/forward.go b/rule/forward.go index a7d350e..2304220 100644 --- a/rule/forward.go +++ b/rule/forward.go @@ -18,6 +18,7 @@ type StatusHandler func(*Forwarder) // Forwarder associates with a `-forward` command, usually a dialer or a chain of dialers. type Forwarder struct { proxy.Dialer + url string addr string priority uint32 maxFailures uint32 // maxfailures to set to Disabled @@ -30,7 +31,7 @@ type Forwarder struct { // ForwarderFromURL parses `forward=` command value and returns a new forwarder. func ForwarderFromURL(s, intface string, dialTimeout, relayTimeout time.Duration) (f *Forwarder, err error) { - f = &Forwarder{} + f = &Forwarder{url: s} ss := strings.Split(s, "#") if len(ss) > 1 { @@ -107,6 +108,11 @@ func (f *Forwarder) Addr() string { return f.addr } +// URL returns the forwarder's full url. +func (f *Forwarder) URL() string { + return f.url +} + // Dial dials to addr and returns conn. func (f *Forwarder) Dial(network, addr string) (c net.Conn, err error) { c, err = f.Dialer.Dial(network, addr)