mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 09:25:41 +08:00
redir, dns: IncFailures on non-timeout errors (#133)
This commit is contained in:
parent
c2d9c67214
commit
22e0576b53
@ -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)
|
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
|
return server, network, dialer.Addr(), respBytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,11 +5,14 @@ import "net"
|
|||||||
// Proxy is a dialer manager
|
// Proxy is a dialer manager
|
||||||
type Proxy interface {
|
type Proxy interface {
|
||||||
// Dial connects to the given address via the proxy.
|
// 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 connects to the given address via the proxy.
|
||||||
DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error)
|
DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error)
|
||||||
|
|
||||||
// Get the dialer by dstAddr
|
// Get the dialer by dstAddr
|
||||||
NextDialer(dstAddr string) Dialer
|
NextDialer(dstAddr string) Dialer
|
||||||
|
|
||||||
|
// Record records result while using the dialer from proxy.
|
||||||
|
Record(dialer Dialer, success bool)
|
||||||
}
|
}
|
||||||
|
@ -104,14 +104,14 @@ func (s *RedirProxy) Serve(c net.Conn) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rc, p, err := s.proxy.Dial("tcp", tgt.String())
|
rc, dialer, err := s.proxy.Dial("tcp", tgt.String())
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
defer rc.Close()
|
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)
|
_, _, err = conn.Relay(c, rc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,6 +119,7 @@ func (s *RedirProxy) Serve(c net.Conn) {
|
|||||||
return // ignore i/o timeout
|
return // ignore i/o timeout
|
||||||
}
|
}
|
||||||
log.F("[redir] relay error: %v", err)
|
log.F("[redir] relay error: %v", err)
|
||||||
|
s.proxy.Record(dialer, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/nadoo/glider/strategy"
|
"github.com/nadoo/glider/strategy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ proxy.Proxy = &Proxy{}
|
||||||
|
|
||||||
// Proxy struct
|
// Proxy struct
|
||||||
type Proxy struct {
|
type Proxy struct {
|
||||||
proxy *strategy.Proxy
|
proxy *strategy.Proxy
|
||||||
@ -47,7 +49,7 @@ func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dial dials to targer addr and return a conn
|
// 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)
|
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)
|
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
|
// AddDomainIP used to update ipMap rules according to domainMap rule
|
||||||
func (p *Proxy) AddDomainIP(domain, ip string) error {
|
func (p *Proxy) AddDomainIP(domain, ip string) error {
|
||||||
if ip != "" {
|
if ip != "" {
|
||||||
|
@ -101,10 +101,6 @@ func (f *Forwarder) Dial(network, addr string) (c net.Conn, err error) {
|
|||||||
c, err = f.Dialer.Dial(network, addr)
|
c, err = f.Dialer.Dial(network, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.IncFailures()
|
f.IncFailures()
|
||||||
if f.Failures() >= f.MaxFailures() && f.Enabled() {
|
|
||||||
f.Disable()
|
|
||||||
log.F("[forwarder] %s reaches maxfailures.", f.addr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, err
|
return c, err
|
||||||
@ -117,7 +113,12 @@ func (f *Forwarder) Failures() uint32 {
|
|||||||
|
|
||||||
// IncFailures increase the failuer count by 1
|
// IncFailures increase the failuer count by 1
|
||||||
func (f *Forwarder) IncFailures() {
|
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
|
// AddHandler adds a custom handler to handle the status change event
|
||||||
|
@ -15,6 +15,8 @@ import (
|
|||||||
"github.com/nadoo/glider/proxy"
|
"github.com/nadoo/glider/proxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ proxy.Proxy = &Proxy{}
|
||||||
|
|
||||||
// Config is strategy config struct.
|
// Config is strategy config struct.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Strategy string
|
Strategy string
|
||||||
@ -102,10 +104,10 @@ func newProxy(fwdrs []*Forwarder, c *Config) *Proxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dial connects to the address addr on the network net.
|
// 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)
|
nd := p.NextDialer(addr)
|
||||||
c, err := nd.Dial(network, addr)
|
c, err := nd.Dial(network, addr)
|
||||||
return c, nd.Addr(), err
|
return c, nd, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialUDP connects to the given address.
|
// DialUDP connects to the given address.
|
||||||
@ -125,6 +127,17 @@ func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
|
|||||||
return p.next(dstAddr)
|
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.
|
// Priority returns the active priority of dialer.
|
||||||
func (p *Proxy) Priority() uint32 { return atomic.LoadUint32(&p.priority) }
|
func (p *Proxy) Priority() uint32 { return atomic.LoadUint32(&p.priority) }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user