general: suport results feedback in more protocols

This commit is contained in:
nadoo 2020-05-01 20:54:23 +08:00
parent c5881a6db3
commit b99a730968
9 changed files with 33 additions and 24 deletions

6
go.mod
View File

@ -11,9 +11,9 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/tjfoc/gmsm v1.3.0 // indirect
github.com/xtaci/kcp-go/v5 v5.5.12
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
golang.org/x/sys v0.0.0-20200428200454-593003d681fa // indirect
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 // indirect
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e // indirect
)
// Replace dependency modules with local developing copy

12
go.sum
View File

@ -60,13 +60,13 @@ golang.org/x/crypto v0.0.0-20191010185427-af544f31c8ac/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc h1:ZGI/fILM2+ueot/UixBSoj9188jCAxVHEZEGhqq67I4=
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -75,8 +75,8 @@ golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191020212454-3e7259c5e7c2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200428200454-593003d681fa h1:yMbJOvnfYkO1dSAviTu/ZguZWLBTXx4xE3LYrxUCCiA=
golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -108,6 +108,7 @@ func (s *HTTP) servHTTPS(r *request, c net.Conn) {
return // ignore i/o timeout
}
log.F("[http] relay error: %v", err)
s.proxy.Record(dialer, false)
}
}

View File

@ -147,6 +147,7 @@ func (s *Socks5) Serve(c net.Conn) {
return // ignore i/o timeout
}
log.F("[socks5] relay error: %v", err)
s.proxy.Record(dialer, false)
}
}

View File

@ -166,8 +166,8 @@ func (s *SS) Serve(c net.Conn) {
return // ignore i/o timeout
}
log.F("[ss] relay error: %v", err)
s.proxy.Record(dialer, false)
}
}
// ListenAndServeUDP serves udp ss requests.

View File

@ -83,6 +83,7 @@ func (s *TCPTun) Serve(c net.Conn) {
rc, dialer, err := s.proxy.Dial("tcp", s.raddr)
if err != nil {
log.F("[tcptun] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), s.addr, dialer.Addr(), err)
s.proxy.Record(dialer, false)
return
}
defer rc.Close()
@ -95,5 +96,6 @@ func (s *TCPTun) Serve(c net.Conn) {
return // ignore i/o timeout
}
log.F("relay error: %v", err)
s.proxy.Record(dialer, false)
}
}

View File

@ -20,7 +20,7 @@ type Proxy struct {
cidrMap sync.Map
}
// NewProxy returns a new rule proxy
// NewProxy returns a new rule proxy.
func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
rd := &Proxy{proxy: proxy}
@ -46,17 +46,17 @@ func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
return rd
}
// 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, proxy.Dialer, error) {
return p.nextProxy(addr).Dial(network, addr)
}
// DialUDP connects to the given address via the proxy
// DialUDP connects to the given address via the proxy.
func (p *Proxy) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
return p.nextProxy(addr).DialUDP(network, addr)
}
// nextProxy return next proxy according to rule
// nextProxy return next proxy according to rule.
func (p *Proxy) nextProxy(dstAddr string) *strategy.Proxy {
host, _, err := net.SplitHostPort(dstAddr)
if err != nil {
@ -104,17 +104,17 @@ func (p *Proxy) nextProxy(dstAddr string) *strategy.Proxy {
return p.proxy
}
// NextDialer return next dialer according to rule
// NextDialer return next dialer according to rule.
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)
strategy.OnRecord(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 {
if ip != "" {
domainParts := strings.Split(domain, ".")

View File

@ -115,6 +115,7 @@ func (f *Forwarder) Failures() uint32 {
func (f *Forwarder) IncFailures() {
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()

View File

@ -65,7 +65,7 @@ func NewProxy(s []string, c *Config) *Proxy {
return newProxy(fwdrs, c)
}
// newProxy returns a new rrProxy
// newProxy returns a new Proxy.
func newProxy(fwdrs []*Forwarder, c *Config) *Proxy {
p := &Proxy{fwdrs: fwdrs, config: c}
sort.Sort(p.fwdrs)
@ -127,12 +127,16 @@ func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
// 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()
OnRecord(dialer, success)
}
func OnRecord(dialer proxy.Dialer, success bool) {
if fwdr, ok := dialer.(*Forwarder); ok {
if success {
fwdr.Enable()
} else {
fwdr.IncFailures()
}
}
}