mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 07:42:38 +08:00 
			
		
		
		
	proxy: support https health checking
This commit is contained in:
		
							parent
							
								
									826695df9a
								
							
						
					
					
						commit
						71c7cd2823
					
				@ -100,10 +100,11 @@ glider -h
 | 
				
			|||||||
<summary>click to see details</summary>
 | 
					<summary>click to see details</summary>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
glider 0.15.1 usage:
 | 
					glider 0.15.2 usage:
 | 
				
			||||||
  -check string
 | 
					  -check string
 | 
				
			||||||
    	check=tcp[://HOST:PORT]: tcp port connect check
 | 
					    	check=tcp[://HOST:PORT]: tcp port connect check
 | 
				
			||||||
    	check=http://HOST[:PORT][/URI][#expect=STRING_IN_RESP_LINE]
 | 
					    	check=http://HOST[:PORT][/URI][#expect=STRING_IN_RESP_LINE]
 | 
				
			||||||
 | 
					      check=https://HOST[:PORT][/URI][#expect=STRING_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
 | 
				
			||||||
    	check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200")
 | 
					    	check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200")
 | 
				
			||||||
  -checkdisabledonly
 | 
					  -checkdisabledonly
 | 
				
			||||||
 | 
				
			|||||||
@ -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.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.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=STRING_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=STRING_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=STRING_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.IntVar(&conf.Strategy.CheckInterval, "checkinterval", 30, "fowarder check interval(seconds)")
 | 
						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.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")
 | 
						flag.IntVar(&conf.Strategy.CheckTolerance, "checktolerance", 0, "fowarder check tolerance(ms), switch only when new_latency < old_latency - tolerance, only used in lha mode")
 | 
				
			||||||
 | 
				
			|||||||
@ -193,6 +193,7 @@ maxfailures=3
 | 
				
			|||||||
# Forwarder health check:
 | 
					# Forwarder health check:
 | 
				
			||||||
# check=tcp[://HOST:PORT]: tcp port connect check
 | 
					# check=tcp[://HOST:PORT]: tcp port connect check
 | 
				
			||||||
# check=http://HOST[:PORT][/URI][#expect=STRING_IN_RESP_LINE]
 | 
					# check=http://HOST[:PORT][/URI][#expect=STRING_IN_RESP_LINE]
 | 
				
			||||||
 | 
					# check=https://HOST[:PORT][/URI][#expect=STRING_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
 | 
				
			||||||
# check=disable: disable health check
 | 
					# check=disable: disable health check
 | 
				
			||||||
check=http://www.msftconnecttest.com/connecttest.txt#expect=200
 | 
					check=http://www.msftconnecttest.com/connecttest.txt#expect=200
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							@ -18,7 +18,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	version = "0.15.1"
 | 
						version = "0.15.2"
 | 
				
			||||||
	config  = parseConfig()
 | 
						config  = parseConfig()
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,11 @@
 | 
				
			|||||||
package rule
 | 
					package rule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/tls"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@ -24,6 +26,9 @@ type tcpChecker struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newTcpChecker(addr string, timeout time.Duration) *tcpChecker {
 | 
					func newTcpChecker(addr string, timeout time.Duration) *tcpChecker {
 | 
				
			||||||
 | 
						if _, port, _ := net.SplitHostPort(addr); port == "" {
 | 
				
			||||||
 | 
							addr = net.JoinHostPort(addr, "80")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return &tcpChecker{addr, timeout}
 | 
						return &tcpChecker{addr, timeout}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,20 +39,33 @@ func (c *tcpChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return 0, err
 | 
							return 0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer rc.Close()
 | 
						rc.Close()
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return time.Since(startTime), nil
 | 
						return time.Since(startTime), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type httpChecker struct {
 | 
					type httpChecker struct {
 | 
				
			||||||
	addr    string
 | 
						addr       string
 | 
				
			||||||
	uri     string
 | 
						uri        string
 | 
				
			||||||
	expect  string
 | 
						expect     string
 | 
				
			||||||
	timeout time.Duration
 | 
						timeout    time.Duration
 | 
				
			||||||
 | 
						tlsConfig  *tls.Config
 | 
				
			||||||
 | 
						serverName string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newHttpChecker(addr, uri, expect string, timeout time.Duration) *httpChecker {
 | 
					func newHttpChecker(addr, uri, expect string, timeout time.Duration, withTLS bool) *httpChecker {
 | 
				
			||||||
	return &httpChecker{addr, uri, expect, timeout}
 | 
						c := &httpChecker{addr: addr, uri: uri, expect: expect, timeout: timeout}
 | 
				
			||||||
 | 
						if _, p, _ := net.SplitHostPort(addr); p == "" {
 | 
				
			||||||
 | 
							if withTLS {
 | 
				
			||||||
 | 
								c.addr = net.JoinHostPort(addr, "443")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								c.addr = net.JoinHostPort(addr, "80")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c.serverName = c.addr[:strings.LastIndex(c.addr, ":")]
 | 
				
			||||||
 | 
						if withTLS {
 | 
				
			||||||
 | 
							c.tlsConfig = &tls.Config{ServerName: c.serverName}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Check implements the Checker interface.
 | 
					// Check implements the Checker interface.
 | 
				
			||||||
@ -57,6 +75,15 @@ func (c *httpChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return 0, err
 | 
							return 0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if c.tlsConfig != nil {
 | 
				
			||||||
 | 
							tlsConn := tls.Client(rc, c.tlsConfig)
 | 
				
			||||||
 | 
							if err := tlsConn.Handshake(); err != nil {
 | 
				
			||||||
 | 
								tlsConn.Close()
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							rc = tlsConn
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	defer rc.Close()
 | 
						defer rc.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if c.timeout > 0 {
 | 
						if c.timeout > 0 {
 | 
				
			||||||
@ -64,7 +91,7 @@ func (c *httpChecker) Check(dialer proxy.Dialer) (time.Duration, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err = io.WriteString(rc,
 | 
						if _, err = io.WriteString(rc,
 | 
				
			||||||
		"GET "+c.uri+" HTTP/1.1\r\nHost:"+c.addr+"\r\nConnection: close"+"\r\n\r\n"); err != nil {
 | 
							"GET "+c.uri+" HTTP/1.1\r\nHost:"+c.serverName+"\r\n\r\n"); err != nil {
 | 
				
			||||||
		return 0, err
 | 
							return 0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Config is config of rule.
 | 
					// Config is config of rule.
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
	Name string
 | 
						RulePath string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Forward  []string
 | 
						Forward  []string
 | 
				
			||||||
	Strategy Strategy
 | 
						Strategy Strategy
 | 
				
			||||||
@ -38,7 +38,7 @@ type Strategy struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NewConfFromFile returns a new config from file.
 | 
					// NewConfFromFile returns a new config from file.
 | 
				
			||||||
func NewConfFromFile(ruleFile string) (*Config, error) {
 | 
					func NewConfFromFile(ruleFile string) (*Config, error) {
 | 
				
			||||||
	p := &Config{Name: ruleFile}
 | 
						p := &Config{RulePath: ruleFile}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f := conflag.NewFromFile("rule", ruleFile)
 | 
						f := conflag.NewFromFile("rule", ruleFile)
 | 
				
			||||||
	f.StringSliceUniqVar(&p.Forward, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
 | 
						f.StringSliceUniqVar(&p.Forward, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"hash/fnv"
 | 
						"hash/fnv"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
@ -24,6 +25,7 @@ func (p priSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// FwdrGroup is a forwarder group.
 | 
					// FwdrGroup is a forwarder group.
 | 
				
			||||||
type FwdrGroup struct {
 | 
					type FwdrGroup struct {
 | 
				
			||||||
 | 
						name     string
 | 
				
			||||||
	config   *Strategy
 | 
						config   *Strategy
 | 
				
			||||||
	fwdrs    priSlice
 | 
						fwdrs    priSlice
 | 
				
			||||||
	avail    []*Forwarder // available forwarders
 | 
						avail    []*Forwarder // available forwarders
 | 
				
			||||||
@ -34,7 +36,7 @@ type FwdrGroup struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewFwdrGroup returns a new forward group.
 | 
					// NewFwdrGroup returns a new forward group.
 | 
				
			||||||
func NewFwdrGroup(name string, s []string, c *Strategy) *FwdrGroup {
 | 
					func NewFwdrGroup(rulePath string, s []string, c *Strategy) *FwdrGroup {
 | 
				
			||||||
	var fwdrs []*Forwarder
 | 
						var fwdrs []*Forwarder
 | 
				
			||||||
	for _, chain := range s {
 | 
						for _, chain := range s {
 | 
				
			||||||
		fwdr, err := ForwarderFromURL(chain, c.IntFace,
 | 
							fwdr, err := ForwarderFromURL(chain, c.IntFace,
 | 
				
			||||||
@ -57,12 +59,13 @@ func NewFwdrGroup(name string, s []string, c *Strategy) *FwdrGroup {
 | 
				
			|||||||
		c.Strategy = "rr"
 | 
							c.Strategy = "rr"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name := strings.TrimSuffix(filepath.Base(rulePath), filepath.Ext(rulePath))
 | 
				
			||||||
	return newFwdrGroup(name, fwdrs, c)
 | 
						return newFwdrGroup(name, fwdrs, c)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newFwdrGroup returns a new FwdrGroup.
 | 
					// newFwdrGroup returns a new FwdrGroup.
 | 
				
			||||||
func newFwdrGroup(name string, fwdrs []*Forwarder, c *Strategy) *FwdrGroup {
 | 
					func newFwdrGroup(name string, fwdrs []*Forwarder, c *Strategy) *FwdrGroup {
 | 
				
			||||||
	p := &FwdrGroup{fwdrs: fwdrs, config: c}
 | 
						p := &FwdrGroup{name: name, fwdrs: fwdrs, config: c}
 | 
				
			||||||
	sort.Sort(p.fwdrs)
 | 
						sort.Sort(p.fwdrs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p.init()
 | 
						p.init()
 | 
				
			||||||
@ -164,8 +167,8 @@ func (p *FwdrGroup) onStatusChanged(fwdr *Forwarder) {
 | 
				
			|||||||
		} else if fwdr.Priority() > p.Priority() {
 | 
							} else if fwdr.Priority() > p.Priority() {
 | 
				
			||||||
			p.init()
 | 
								p.init()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		log.F("[group] %s(%d) changed status from DISABLED to ENABLED (%d of %d currently enabled)",
 | 
							log.F("[group] %s: %s(%d) changed status from DISABLED to ENABLED (%d of %d currently enabled)",
 | 
				
			||||||
			fwdr.Addr(), fwdr.Priority(), len(p.avail), len(p.fwdrs))
 | 
								p.name, fwdr.Addr(), fwdr.Priority(), len(p.avail), len(p.fwdrs))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		for i, f := range p.avail {
 | 
							for i, f := range p.avail {
 | 
				
			||||||
			if f == fwdr {
 | 
								if f == fwdr {
 | 
				
			||||||
@ -173,8 +176,8 @@ func (p *FwdrGroup) onStatusChanged(fwdr *Forwarder) {
 | 
				
			|||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		log.F("[group] %s(%d) changed status from ENABLED to DISABLED (%d of %d currently enabled)",
 | 
							log.F("[group] %s: %s(%d) changed status from ENABLED to DISABLED (%d of %d currently enabled)",
 | 
				
			||||||
			fwdr.Addr(), fwdr.Priority(), len(p.avail), len(p.fwdrs))
 | 
								p.name, fwdr.Addr(), fwdr.Priority(), len(p.avail), len(p.fwdrs))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(p.avail) == 0 {
 | 
						if len(p.avail) == 0 {
 | 
				
			||||||
@ -185,7 +188,7 @@ func (p *FwdrGroup) onStatusChanged(fwdr *Forwarder) {
 | 
				
			|||||||
// Check runs the forwarder checks.
 | 
					// Check runs the forwarder checks.
 | 
				
			||||||
func (p *FwdrGroup) Check() {
 | 
					func (p *FwdrGroup) Check() {
 | 
				
			||||||
	if len(p.fwdrs) == 1 {
 | 
						if len(p.fwdrs) == 1 {
 | 
				
			||||||
		log.F("[group] only 1 forwarder found, disable health checking")
 | 
							log.F("[group] %s: only 1 forwarder found, disable health checking", p.name)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -195,36 +198,32 @@ func (p *FwdrGroup) Check() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	u, err := url.Parse(p.config.Check)
 | 
						u, err := url.Parse(p.config.Check)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.F("[group] parse check config error: %s, disable health checking", err)
 | 
							log.F("[group] %s: parse check config error: %s, disable health checking", p.name, err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr := u.Host
 | 
						addr := u.Host
 | 
				
			||||||
	if _, port, _ := net.SplitHostPort(addr); port == "" {
 | 
					 | 
				
			||||||
		addr = net.JoinHostPort(addr, "80")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	timeout := time.Duration(p.config.CheckTimeout) * time.Second
 | 
						timeout := time.Duration(p.config.CheckTimeout) * time.Second
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var checker Checker
 | 
						var checker Checker
 | 
				
			||||||
	switch u.Scheme {
 | 
						switch u.Scheme {
 | 
				
			||||||
	case "tcp":
 | 
						case "tcp":
 | 
				
			||||||
		checker = newTcpChecker(addr, timeout)
 | 
							checker = newTcpChecker(addr, timeout)
 | 
				
			||||||
	case "http":
 | 
						case "http", "https":
 | 
				
			||||||
		expect := "HTTP" // default: check the first 4 chars in response
 | 
							expect := "HTTP" // default: check the first 4 chars in response
 | 
				
			||||||
		params, _ := url.ParseQuery(u.Fragment)
 | 
							params, _ := url.ParseQuery(u.Fragment)
 | 
				
			||||||
		if ex := params.Get("expect"); ex != "" {
 | 
							if ex := params.Get("expect"); ex != "" {
 | 
				
			||||||
			expect = ex
 | 
								expect = ex
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		checker = newHttpChecker(addr, u.RequestURI(), expect, timeout)
 | 
							checker = newHttpChecker(addr, u.RequestURI(), expect, timeout, u.Scheme == "https")
 | 
				
			||||||
	case "file":
 | 
						case "file":
 | 
				
			||||||
		checker = newFileChecker(u.Host + u.Path)
 | 
							checker = newFileChecker(u.Host + u.Path)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		log.F("[group] check config `%s`, disable health checking", p.config.Check)
 | 
							log.F("[group] %s: unknown scheme in check config `%s`, disable health checking", p.name, p.config.Check)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.F("[group] using check config: %s", p.config.Check)
 | 
						log.F("[group] %s: using check config: %s", p.name, p.config.Check)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < len(p.fwdrs); i++ {
 | 
						for i := 0; i < len(p.fwdrs); i++ {
 | 
				
			||||||
		go p.check(p.fwdrs[i], checker)
 | 
							go p.check(p.fwdrs[i], checker)
 | 
				
			||||||
@ -251,7 +250,7 @@ func (p *FwdrGroup) check(fwdr *Forwarder, checker Checker) {
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			if errors.Is(err, proxy.ErrNotSupported) {
 | 
								if errors.Is(err, proxy.ErrNotSupported) {
 | 
				
			||||||
				fwdr.SetMaxFailures(0)
 | 
									fwdr.SetMaxFailures(0)
 | 
				
			||||||
				log.F("[check] %s(%d), %s, stop checking", fwdr.Addr(), fwdr.Priority(), err)
 | 
									log.F("[check] %s: %s(%d), %s, stop checking", p.name, fwdr.Addr(), fwdr.Priority(), err)
 | 
				
			||||||
				fwdr.Enable()
 | 
									fwdr.Enable()
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@ -261,14 +260,15 @@ func (p *FwdrGroup) check(fwdr *Forwarder, checker Checker) {
 | 
				
			|||||||
				wait = 16
 | 
									wait = 16
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			log.F("[check] %s(%d), FAILED. error: %s", fwdr.Addr(), fwdr.Priority(), err)
 | 
								log.F("[check] %s: %s(%d), FAILED. error: %s", p.name, fwdr.Addr(), fwdr.Priority(), err)
 | 
				
			||||||
			fwdr.Disable()
 | 
								fwdr.Disable()
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wait = 1
 | 
							wait = 1
 | 
				
			||||||
		fwdr.SetLatency(int64(elapsed))
 | 
							fwdr.SetLatency(int64(elapsed))
 | 
				
			||||||
		log.F("[check] %s(%d), SUCCESS. elapsed: %s", fwdr.Addr(), fwdr.Priority(), elapsed)
 | 
							log.F("[check] %s: %s(%d), SUCCESS. elapsed: %s",
 | 
				
			||||||
 | 
								p.name, fwdr.Addr(), fwdr.Priority(), elapsed)
 | 
				
			||||||
		fwdr.Enable()
 | 
							fwdr.Enable()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ func NewProxy(mainForwarders []string, mainStrategy *Strategy, rules []*Config)
 | 
				
			|||||||
	rd := &Proxy{main: NewFwdrGroup("main", mainForwarders, mainStrategy)}
 | 
						rd := &Proxy{main: NewFwdrGroup("main", mainForwarders, mainStrategy)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, r := range rules {
 | 
						for _, r := range rules {
 | 
				
			||||||
		group := NewFwdrGroup(r.Name, r.Forward, &r.Strategy)
 | 
							group := NewFwdrGroup(r.RulePath, r.Forward, &r.Strategy)
 | 
				
			||||||
		rd.all = append(rd.all, group)
 | 
							rd.all = append(rd.all, group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, domain := range r.Domain {
 | 
							for _, domain := range r.Domain {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user