redir, dns: IncFailures on non-timeout errors (#133)

This commit is contained in:
wuudjac 2020-04-28 15:18:19 +08:00 committed by GitHub
parent c2d9c67214
commit 22e0576b53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 12 deletions

View File

@ -175,6 +175,9 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (
log.F("[dns] error in resolving %s, failed to exchange with server %v: %v", qname, server, err)
}
if err != nil {
c.proxy.Record(dialer, false)
}
return server, network, dialer.Addr(), respBytes, err
}

View File

@ -5,11 +5,14 @@ import "net"
// Proxy is a dialer manager
type Proxy interface {
// Dial connects to the given address via the proxy.
Dial(network, addr string) (c net.Conn, proxy string, err error)
Dial(network, addr string) (c net.Conn, dialer Dialer, err error)
// DialUDP connects to the given address via the proxy.
DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error)
// Get the dialer by dstAddr
NextDialer(dstAddr string) Dialer
// Record records result while using the dialer from proxy.
Record(dialer Dialer, success bool)
}

View File

@ -104,14 +104,14 @@ func (s *RedirProxy) Serve(c net.Conn) {
return
}
rc, p, err := s.proxy.Dial("tcp", tgt.String())
rc, dialer, err := s.proxy.Dial("tcp", tgt.String())
if err != nil {
log.F("[redir] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), tgt, p, err)
log.F("[redir] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), tgt, dialer.Addr(), err)
return
}
defer rc.Close()
log.F("[redir] %s <-> %s via %s", c.RemoteAddr(), tgt, p)
log.F("[redir] %s <-> %s via %s", c.RemoteAddr(), tgt, dialer.Addr())
_, _, err = conn.Relay(c, rc)
if err != nil {
@ -119,6 +119,7 @@ func (s *RedirProxy) Serve(c net.Conn) {
return // ignore i/o timeout
}
log.F("[redir] relay error: %v", err)
s.proxy.Record(dialer, false)
}
}

View File

@ -10,6 +10,8 @@ import (
"github.com/nadoo/glider/strategy"
)
var _ proxy.Proxy = &Proxy{}
// Proxy struct
type Proxy struct {
proxy *strategy.Proxy
@ -47,7 +49,7 @@ func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
}
// Dial dials to targer addr and return a conn
func (p *Proxy) Dial(network, addr string) (net.Conn, string, error) {
func (p *Proxy) Dial(network, addr string) (net.Conn, proxy.Dialer, error) {
return p.nextProxy(addr).Dial(network, addr)
}
@ -109,6 +111,11 @@ func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
return p.nextProxy(dstAddr).NextDialer(dstAddr)
}
// Record records result while using the dialer from proxy.
func (p *Proxy) Record(dialer proxy.Dialer, success bool) {
p.proxy.Record(dialer, success)
}
// AddDomainIP used to update ipMap rules according to domainMap rule
func (p *Proxy) AddDomainIP(domain, ip string) error {
if ip != "" {

View File

@ -101,10 +101,6 @@ func (f *Forwarder) Dial(network, addr string) (c net.Conn, err error) {
c, err = f.Dialer.Dial(network, addr)
if err != nil {
f.IncFailures()
if f.Failures() >= f.MaxFailures() && f.Enabled() {
f.Disable()
log.F("[forwarder] %s reaches maxfailures.", f.addr)
}
}
return c, err
@ -117,7 +113,12 @@ func (f *Forwarder) Failures() uint32 {
// IncFailures increase the failuer count by 1
func (f *Forwarder) IncFailures() {
atomic.AddUint32(&f.failures, 1)
failures := atomic.AddUint32(&f.failures, 1)
log.F("[forwarder] %s recorded %d failures", f.addr, failures)
if failures >= f.MaxFailures() && f.Enabled() {
log.F("[forwarder] %s reaches maxfailures.", f.addr)
f.Disable()
}
}
// AddHandler adds a custom handler to handle the status change event

View File

@ -15,6 +15,8 @@ import (
"github.com/nadoo/glider/proxy"
)
var _ proxy.Proxy = &Proxy{}
// Config is strategy config struct.
type Config struct {
Strategy string
@ -102,10 +104,10 @@ func newProxy(fwdrs []*Forwarder, c *Config) *Proxy {
}
// Dial connects to the address addr on the network net.
func (p *Proxy) Dial(network, addr string) (net.Conn, string, error) {
func (p *Proxy) Dial(network, addr string) (net.Conn, proxy.Dialer, error) {
nd := p.NextDialer(addr)
c, err := nd.Dial(network, addr)
return c, nd.Addr(), err
return c, nd, err
}
// DialUDP connects to the given address.
@ -125,6 +127,17 @@ func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
return p.next(dstAddr)
}
// Record records result while using the dialer from proxy.
func (p *Proxy) Record(dialer proxy.Dialer, success bool) {
if success {
return
}
forwarder, ok := dialer.(*Forwarder)
if ok {
forwarder.IncFailures()
}
}
// Priority returns the active priority of dialer.
func (p *Proxy) Priority() uint32 { return atomic.LoadUint32(&p.priority) }