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/pkg/errors v0.9.1 // indirect
github.com/tjfoc/gmsm v1.3.0 // indirect github.com/tjfoc/gmsm v1.3.0 // indirect
github.com/xtaci/kcp-go/v5 v5.5.12 github.com/xtaci/kcp-go/v5 v5.5.12
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 // indirect
golang.org/x/sys v0.0.0-20200428200454-593003d681fa // indirect golang.org/x/sys v0.0.0-20200501052902-10377860bb8e // indirect
) )
// Replace dependency modules with local developing copy // 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-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-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-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-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-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-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-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-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/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-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-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-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-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc=
golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= 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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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 return // ignore i/o timeout
} }
log.F("[http] relay error: %v", err) 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 return // ignore i/o timeout
} }
log.F("[socks5] relay error: %v", err) 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 return // ignore i/o timeout
} }
log.F("[ss] relay error: %v", err) log.F("[ss] relay error: %v", err)
s.proxy.Record(dialer, false)
} }
} }
// ListenAndServeUDP serves udp ss requests. // 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) rc, dialer, err := s.proxy.Dial("tcp", s.raddr)
if err != nil { if err != nil {
log.F("[tcptun] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), s.addr, dialer.Addr(), err) log.F("[tcptun] %s <-> %s via %s, error in dial: %v", c.RemoteAddr(), s.addr, dialer.Addr(), err)
s.proxy.Record(dialer, false)
return return
} }
defer rc.Close() defer rc.Close()
@ -95,5 +96,6 @@ func (s *TCPTun) Serve(c net.Conn) {
return // ignore i/o timeout return // ignore i/o timeout
} }
log.F("relay error: %v", err) log.F("relay error: %v", err)
s.proxy.Record(dialer, false)
} }
} }

View File

@ -20,7 +20,7 @@ type Proxy struct {
cidrMap sync.Map cidrMap sync.Map
} }
// NewProxy returns a new rule proxy // NewProxy returns a new rule proxy.
func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy { func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
rd := &Proxy{proxy: proxy} rd := &Proxy{proxy: proxy}
@ -46,17 +46,17 @@ func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
return rd 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) { 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)
} }
// 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) { func (p *Proxy) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
return p.nextProxy(addr).DialUDP(network, addr) 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 { func (p *Proxy) nextProxy(dstAddr string) *strategy.Proxy {
host, _, err := net.SplitHostPort(dstAddr) host, _, err := net.SplitHostPort(dstAddr)
if err != nil { if err != nil {
@ -104,17 +104,17 @@ func (p *Proxy) nextProxy(dstAddr string) *strategy.Proxy {
return p.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 { 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. // Record records result while using the dialer from proxy.
func (p *Proxy) Record(dialer proxy.Dialer, success bool) { 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 { func (p *Proxy) AddDomainIP(domain, ip string) error {
if ip != "" { if ip != "" {
domainParts := strings.Split(domain, ".") domainParts := strings.Split(domain, ".")

View File

@ -115,6 +115,7 @@ func (f *Forwarder) Failures() uint32 {
func (f *Forwarder) IncFailures() { func (f *Forwarder) IncFailures() {
failures := atomic.AddUint32(&f.failures, 1) failures := atomic.AddUint32(&f.failures, 1)
log.F("[forwarder] %s recorded %d failures", f.addr, failures) log.F("[forwarder] %s recorded %d failures", f.addr, failures)
if failures >= f.MaxFailures() && f.Enabled() { if failures >= f.MaxFailures() && f.Enabled() {
log.F("[forwarder] %s reaches maxfailures.", f.addr) log.F("[forwarder] %s reaches maxfailures.", f.addr)
f.Disable() f.Disable()

View File

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