strategy: add checktimeout config. (#89)

This commit is contained in:
nadoo 2019-03-18 23:37:01 +08:00
parent 47406ce4ce
commit a22b1d9c86
12 changed files with 91 additions and 74 deletions

View File

@ -116,9 +116,11 @@ glider -config CONFIGPATH -listen :8080 -verbose
## Usage
```bash
glider v0.6.10 usage:
glider v0.7.0 usage:
-checkinterval int
proxy check interval(seconds) (default 30)
-checktimeout int
proxy check timeout(seconds) (default 10)
-checkwebsite string
proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80 (default "www.apple.com")
-config string
@ -139,6 +141,8 @@ glider v0.6.10 usage:
timeout value used in multiple dnsservers switch(seconds) (default 3)
-forward value
forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]
-include value
include file
-interface string
source ip or source interface
-listen value

View File

@ -7,41 +7,35 @@ import (
"time"
)
// UDPBufSize is the size of udp buffer
// UDPBufSize is the size of udp buffer.
const UDPBufSize = 65536
// Conn struct
// Conn is a base conn struct.
type Conn struct {
r *bufio.Reader
net.Conn
}
// NewConn .
// NewConn returns a new conn.
func NewConn(c net.Conn) *Conn {
return &Conn{bufio.NewReader(c), c}
}
// NewConnSize .
func NewConnSize(c net.Conn, n int) *Conn {
return &Conn{bufio.NewReaderSize(c, n), c}
}
// Peek .
// Peek returns the next n bytes without advancing the reader.
func (c *Conn) Peek(n int) ([]byte, error) {
return c.r.Peek(n)
}
// Read .
func (c *Conn) Read(p []byte) (int, error) {
return c.r.Read(p)
}
// Reader returns the internal bufio.Reader
// Reader returns the internal bufio.Reader.
func (c *Conn) Reader() *bufio.Reader {
return c.r
}
// Relay .
// Relay relays between left and right.
func Relay(left, right net.Conn) (int64, int64, error) {
type res struct {
N int64
@ -67,8 +61,8 @@ func Relay(left, right net.Conn) (int64, int64, error) {
return n, rs.N, err
}
// TimedCopy copy from src to dst at target with read timeout
func TimedCopy(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration) error {
// RelayUDP copys from src to dst at target with read timeout.
func RelayUDP(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout time.Duration) error {
buf := make([]byte, UDPBufSize)
for {
src.SetReadDeadline(time.Now().Add(timeout))
@ -84,7 +78,7 @@ func TimedCopy(dst net.PacketConn, target net.Addr, src net.PacketConn, timeout
}
}
// OutboundIP returns preferred outbound ip of this machine
// OutboundIP returns preferred outbound ip of this machine.
func OutboundIP() string {
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {

View File

@ -40,6 +40,7 @@ func confInit() {
flag.StringVar(&conf.StrategyConfig.Strategy, "strategy", "rr", "forward strategy, default: rr")
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.CheckTimeout, "checktimeout", 10, "proxy check timeout(seconds)")
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")

View File

@ -155,6 +155,8 @@ checkwebsite=www.apple.com
# check interval(seconds)
checkinterval=30
# check timeout(seconds)
checktimeout=10
# DNS FORWARDING SERVER
# ----------------

6
go.mod
View File

@ -19,9 +19,9 @@ require (
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
github.com/tjfoc/gmsm v1.0.1 // indirect
github.com/xtaci/kcp-go v5.0.7+incompatible
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 // indirect
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f // indirect
)
// Replace dependency modules with local developing copy

6
go.sum
View File

@ -38,6 +38,8 @@ golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exqr0evNhKRNe5K/gi+zKh4U=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 h1:fY7Dsw114eJN4boqzVSbpVHO6rTdhq6/GnXeu+PKnzU=
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190310074541-c10a0554eabf h1:J7RqX9u0J9ZB37CGaFc2VC+QZZT6E6jnDbrboEFVo0U=
@ -46,6 +48,8 @@ golang.org/x/net v0.0.0-20190311031020-56fb01167e7d h1:vQJbQvu6+H699vOmHa20TEBI9
golang.org/x/net v0.0.0-20190311031020-56fb01167e7d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10 h1:xQJI9OEiErEQ++DoXOHqEpzsGMrAv2Q2jyCpi7DmfpQ=
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -69,4 +73,6 @@ golang.org/x/sys v0.0.0-20190311152110-c8c8c57fd1e1 h1:FQNj2xvjQ1lgFyzbSybGZr792
golang.org/x/sys v0.0.0-20190311152110-c8c8c57fd1e1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f h1:yCrMx/EeIue0+Qca57bWZS7VX6ymEoypmhWyPhz0NHM=
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -26,10 +26,10 @@ import (
"github.com/nadoo/glider/proxy"
)
// Version is socks5 version number
// Version is socks5 version number.
const Version = 5
// SOCKS5 struct
// SOCKS5 is a base socks5 struct.
type SOCKS5 struct {
dialer proxy.Dialer
addr string
@ -43,7 +43,7 @@ func init() {
}
// NewSOCKS5 returns a Proxy that makes SOCKS v5 connections to the given address
// with an optional username and password. See RFC 1928
// with an optional username and password. (RFC 1928)
func NewSOCKS5(s string, dialer proxy.Dialer) (*SOCKS5, error) {
u, err := url.Parse(s)
if err != nil {
@ -65,23 +65,23 @@ func NewSOCKS5(s string, dialer proxy.Dialer) (*SOCKS5, error) {
return h, nil
}
// NewSocks5Dialer returns a socks5 proxy dialer
// NewSocks5Dialer returns a socks5 proxy dialer.
func NewSocks5Dialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
return NewSOCKS5(s, dialer)
}
// NewSocks5Server returns a socks5 proxy server
// NewSocks5Server returns a socks5 proxy server.
func NewSocks5Server(s string, dialer proxy.Dialer) (proxy.Server, error) {
return NewSOCKS5(s, dialer)
}
// ListenAndServe serves socks5 requests
// ListenAndServe serves socks5 requests.
func (s *SOCKS5) ListenAndServe() {
go s.ListenAndServeUDP()
s.ListenAndServeTCP()
}
// ListenAndServeTCP .
// ListenAndServeTCP listen and serve on tcp port.
func (s *SOCKS5) ListenAndServeTCP() {
l, err := net.Listen("tcp", s.addr)
if err != nil {
@ -102,7 +102,7 @@ func (s *SOCKS5) ListenAndServeTCP() {
}
}
// Serve .
// Serve serves a connection.
func (s *SOCKS5) Serve(c net.Conn) {
defer c.Close()
@ -148,7 +148,7 @@ func (s *SOCKS5) Serve(c net.Conn) {
}
}
// ListenAndServeUDP serves udp requests
// ListenAndServeUDP serves udp requests.
func (s *SOCKS5) ListenAndServeUDP() {
lc, err := net.ListenPacket("udp", s.addr)
if err != nil {
@ -189,7 +189,7 @@ func (s *SOCKS5) ListenAndServeUDP() {
nm.Store(raddr.String(), pc)
go func() {
conn.TimedCopy(c, raddr, pc, 2*time.Minute)
conn.RelayUDP(c, raddr, pc, 2*time.Minute)
pc.Close()
nm.Delete(raddr.String())
}()
@ -211,7 +211,7 @@ func (s *SOCKS5) ListenAndServeUDP() {
}
// Addr returns forwarder's address
// Addr returns forwarder's address.
func (s *SOCKS5) Addr() string {
if s.addr == "" {
return s.dialer.Addr()
@ -219,7 +219,7 @@ func (s *SOCKS5) Addr() string {
return s.addr
}
// NextDialer returns the next dialer
// NextDialer returns the next dialer.
func (s *SOCKS5) NextDialer(dstAddr string) proxy.Dialer { return s.dialer.NextDialer(dstAddr) }
// Dial connects to the address addr on the network net via the SOCKS5 proxy.
@ -244,7 +244,7 @@ func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
return c, nil
}
// DialUDP connects to the given address via the proxy
// DialUDP connects to the given address via the proxy.
func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
c, err := s.dialer.Dial("tcp", s.addr)
if err != nil {
@ -293,7 +293,7 @@ func (s *SOCKS5) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.A
// connect takes an existing connection to a socks5 proxy server,
// and commands the server to extend that connection to target,
// which must be a canonical address with a host and port
// which must be a canonical address with a host and port.
func (s *SOCKS5) connect(conn net.Conn, target string) error {
host, portStr, err := net.SplitHostPort(target)
if err != nil {
@ -424,7 +424,7 @@ func (s *SOCKS5) connect(conn net.Conn, target string) error {
return nil
}
// Handshake fast-tracks SOCKS initialization to get target address to connect
// Handshake fast-tracks SOCKS initialization to get target address to connect.
func (s *SOCKS5) handshake(rw io.ReadWriter) (socks.Addr, error) {
// Read RFC 1928 for request and reply structure and sizes
buf := make([]byte, socks.MaxAddrLen)

View File

@ -16,7 +16,7 @@ import (
"github.com/nadoo/glider/proxy"
)
// SS .
// SS is a base ss struct.
type SS struct {
dialer proxy.Dialer
addr string
@ -29,7 +29,7 @@ func init() {
proxy.RegisterServer("ss", NewSSServer)
}
// NewSS returns a shadowsocks proxy
// NewSS returns a ss proxy.
func NewSS(s string, dialer proxy.Dialer) (*SS, error) {
u, err := url.Parse(s)
if err != nil {
@ -55,23 +55,23 @@ func NewSS(s string, dialer proxy.Dialer) (*SS, error) {
return p, nil
}
// NewSSDialer returns a ss proxy dialer
// NewSSDialer returns a ss proxy dialer.
func NewSSDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
return NewSS(s, dialer)
}
// NewSSServer returns a ss proxy server
// NewSSServer returns a ss proxy server.
func NewSSServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
return NewSS(s, dialer)
}
// ListenAndServe serves ss requests
// ListenAndServe serves ss requests.
func (s *SS) ListenAndServe() {
go s.ListenAndServeUDP()
s.ListenAndServeTCP()
}
// ListenAndServeTCP serves tcp ss requests
// ListenAndServeTCP serves tcp ss requests.
func (s *SS) ListenAndServeTCP() {
l, err := net.Listen("tcp", s.addr)
if err != nil {
@ -92,7 +92,7 @@ func (s *SS) ListenAndServeTCP() {
}
// Serve serves tcp ss requests
// Serve serves a connection.
func (s *SS) Serve(c net.Conn) {
defer c.Close()
@ -166,7 +166,7 @@ func (s *SS) Serve(c net.Conn) {
}
// ListenAndServeUDP serves udp ss requests
// ListenAndServeUDP serves udp ss requests.
func (s *SS) ListenAndServeUDP() {
lc, err := net.ListenPacket("udp", s.addr)
if err != nil {
@ -204,7 +204,7 @@ func (s *SS) ListenAndServeUDP() {
nm.Store(raddr.String(), pc)
go func() {
conn.TimedCopy(c, raddr, pc, 2*time.Minute)
conn.RelayUDP(c, raddr, pc, 2*time.Minute)
pc.Close()
nm.Delete(raddr.String())
}()
@ -225,12 +225,12 @@ func (s *SS) ListenAndServeUDP() {
}
}
// ListCipher .
// ListCipher returns all the ciphers supported.
func ListCipher() string {
return strings.Join(core.ListCipher(), " ")
}
// Addr returns forwarder's address
// Addr returns forwarder's address.
func (s *SS) Addr() string {
if s.addr == "" {
return s.dialer.Addr()
@ -238,7 +238,7 @@ func (s *SS) Addr() string {
return s.addr
}
// NextDialer returns the next dialer
// NextDialer returns the next dialer.
func (s *SS) NextDialer(dstAddr string) proxy.Dialer { return s.dialer.NextDialer(dstAddr) }
// Dial connects to the address addr on the network net via the proxy.
@ -268,7 +268,7 @@ func (s *SS) Dial(network, addr string) (net.Conn, error) {
}
// DialUDP connects to the given address via the proxy
// DialUDP connects to the given address via the proxy.
func (s *SS) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) {
pc, nextHop, err := s.dialer.DialUDP(network, s.addr)
if err != nil {

View File

@ -16,8 +16,8 @@ import (
type UDPTun struct {
dialer proxy.Dialer
addr string
taddr string // tunnel addr
uaddr *net.UDPAddr // tunnel addr
taddr string // tunnel addr string
tuaddr *net.UDPAddr // tunnel addr
}
func init() {
@ -41,7 +41,7 @@ func NewUDPTun(s string, dialer proxy.Dialer) (*UDPTun, error) {
taddr: d[1],
}
p.uaddr, err = net.ResolveUDPAddr("udp", p.taddr)
p.tuaddr, err = net.ResolveUDPAddr("udp", p.taddr)
return p, err
}
@ -85,7 +85,7 @@ func (s *UDPTun) ListenAndServe() {
nm.Store(raddr.String(), pc)
go func() {
conn.TimedCopy(c, raddr, pc, 2*time.Minute)
conn.RelayUDP(c, raddr, pc, 2*time.Minute)
pc.Close()
nm.Delete(raddr.String())
}()
@ -94,7 +94,7 @@ func (s *UDPTun) ListenAndServe() {
pc = v.(net.PacketConn)
}
_, err = pc.WriteTo(buf[:n], s.uaddr)
_, err = pc.WriteTo(buf[:n], s.tuaddr)
if err != nil {
log.F("[udptun] remote write error: %v", err)
continue

View File

@ -12,7 +12,7 @@ import (
"github.com/nadoo/glider/proxy"
)
// UoTTun udp over tcp tunnel
// UoTTun is a base udp over tcp tunnel struct.
type UoTTun struct {
dialer proxy.Dialer
addr string
@ -24,7 +24,7 @@ func init() {
proxy.RegisterServer("uottun", NewUoTTunServer)
}
// NewUoTTun returns a UoTTun proxy
// NewUoTTun returns a UoTTun proxy.
func NewUoTTun(s string, dialer proxy.Dialer) (*UoTTun, error) {
u, err := url.Parse(s)
if err != nil {
@ -44,12 +44,12 @@ func NewUoTTun(s string, dialer proxy.Dialer) (*UoTTun, error) {
return p, nil
}
// NewUoTTunServer returns a uot tunnel server
// NewUoTTunServer returns a uot tunnel server.
func NewUoTTunServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
return NewUoTTun(s, dialer)
}
// ListenAndServe .
// ListenAndServe listen and serve on tcp.
func (s *UoTTun) ListenAndServe() {
c, err := net.ListenPacket("udp", s.addr)
if err != nil {
@ -78,7 +78,7 @@ func (s *UoTTun) ListenAndServe() {
go func() {
// no remote forwarder, just a local udp forwarder
if urc, ok := rc.(*net.UDPConn); ok {
conn.TimedCopy(c, clientAddr, urc, 2*time.Minute)
conn.RelayUDP(c, clientAddr, urc, 2*time.Minute)
urc.Close()
return
}
@ -103,7 +103,7 @@ func (s *UoTTun) ListenAndServe() {
}
}
// Serve .
// Serve is not allowed to be called directly.
func (s *UoTTun) Serve(c net.Conn) {
// TODO
log.F("[uottun] func Serve: can not be called directly")

View File

@ -35,6 +35,7 @@ func NewConfFromFile(ruleFile string) (*Config, error) {
f.StringVar(&p.StrategyConfig.Strategy, "strategy", "rr", "forward strategy, default: rr")
f.StringVar(&p.StrategyConfig.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
f.IntVar(&p.StrategyConfig.CheckInterval, "checkinterval", 30, "proxy check interval(seconds)")
f.IntVar(&p.StrategyConfig.CheckTimeout, "checktimeout", 10, "proxy check timeout(seconds)")
f.StringVar(&p.StrategyConfig.IntFace, "interface", "", "source ip or source interface")
f.StringSliceUniqVar(&p.DNSServers, "dnsserver", nil, "remote dns server")

View File

@ -15,16 +15,17 @@ import (
"github.com/nadoo/glider/proxy"
)
// Checker is an interface of forwarder checker
// Checker is an interface of forwarder checker.
type Checker interface {
Check()
}
// Config of strategy
// Config is strategy config struct.
type Config struct {
Strategy string
CheckWebSite string
CheckInterval int
CheckTimeout int
MaxFailures int
IntFace string
}
@ -36,7 +37,7 @@ func (p priSlice) Len() int { return len(p) }
func (p priSlice) Less(i, j int) bool { return p[i].Priority() > p[j].Priority() }
func (p priSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Dialer .
// Dialer is base dialer struct.
type Dialer struct {
config *Config
fwdrs priSlice
@ -48,7 +49,7 @@ type Dialer struct {
nextForwarder func(addr string) *proxy.Forwarder
}
// NewDialer returns a new strategy dialer
// NewDialer returns a new strategy dialer.
func NewDialer(s []string, c *Config) proxy.Dialer {
var fwdrs []*proxy.Forwarder
for _, chain := range s {
@ -111,20 +112,20 @@ func newDialer(fwdrs []*proxy.Forwarder, c *Config) *Dialer {
return d
}
// Addr returns forwarder's address
// Addr returns forwarder's address.
func (d *Dialer) Addr() string { return "STRATEGY" }
// Dial connects to the address addr on the network net
// Dial connects to the address addr on the network net.
func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
return d.NextDialer(addr).Dial(network, addr)
}
// DialUDP connects to the given address
// DialUDP connects to the given address.
func (d *Dialer) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
return d.NextDialer(addr).DialUDP(network, addr)
}
// NextDialer returns the next dialer
// NextDialer returns the next dialer.
func (d *Dialer) NextDialer(dstAddr string) proxy.Dialer {
d.mu.RLock()
defer d.mu.RUnlock()
@ -132,13 +133,13 @@ func (d *Dialer) NextDialer(dstAddr string) proxy.Dialer {
return d.nextForwarder(dstAddr)
}
// Priority returns the active priority of dialer
// Priority returns the active priority of dialer.
func (d *Dialer) Priority() uint32 { return atomic.LoadUint32(&d.priority) }
// SetPriority sets the active priority of daler
// SetPriority sets the active priority of daler.
func (d *Dialer) SetPriority(p uint32) { atomic.StoreUint32(&d.priority, p) }
// initAvailable traverse d.fwdrs and init the available forwarder slice
// initAvailable traverse d.fwdrs and init the available forwarder slice.
func (d *Dialer) initAvailable() {
for _, f := range d.fwdrs {
if f.Enabled() {
@ -162,7 +163,7 @@ func (d *Dialer) initAvailable() {
}
}
// onStatusChanged will be called when fwdr's status changed
// onStatusChanged will be called when fwdr's status changed.
func (d *Dialer) onStatusChanged(fwdr *proxy.Forwarder) {
d.mu.Lock()
defer d.mu.Unlock()
@ -189,7 +190,7 @@ func (d *Dialer) onStatusChanged(fwdr *proxy.Forwarder) {
}
}
// Check implements the Checker interface
// Check implements the Checker interface.
func (d *Dialer) Check() {
for i := 0; i < len(d.fwdrs); i++ {
go d.check(i)
@ -229,11 +230,19 @@ func (d *Dialer) check(i int) {
f.Disable()
log.F("[check] %s(%d) -> %s, DISABLED. error in read: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, err)
} else if bytes.Equal([]byte("HTTP"), buf) {
f.Enable()
retry = 2
readTime := time.Since(startTime)
f.SetLatency(int64(readTime))
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, readTime.String())
if readTime > time.Duration(d.config.CheckTimeout)*time.Second {
f.Disable()
log.F("[check] %s(%d) -> %s, DISABLED. connect timeout: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, readTime)
} else {
retry = 2
f.Enable()
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, readTime)
}
} else {
f.Disable()
log.F("[check] %s(%d) -> %s, DISABLED. server response: %s", f.Addr(), f.Priority(), d.config.CheckWebSite, buf)