add timeout for handshake but not for target connecting
better algorithm for backend retry
This commit is contained in:
parent
c66751b017
commit
1823009c5c
42
chain.go
42
chain.go
@ -106,7 +106,7 @@ func (c *Chain) Dial(addr string, opts ...ChainOption) (conn net.Conn, err error
|
|||||||
opt(options)
|
opt(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
retries := 1
|
retries := 10 //maximum retry
|
||||||
if c != nil && c.Retries > 0 {
|
if c != nil && c.Retries > 0 {
|
||||||
retries = c.Retries
|
retries = c.Retries
|
||||||
}
|
}
|
||||||
@ -119,6 +119,9 @@ func (c *Chain) Dial(addr string, opts ...ChainOption) (conn net.Conn, err error
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if err == ErrNoneAvailable {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -128,6 +131,7 @@ func (c *Chain) dialWithOptions(addr string, options *ChainOptions) (net.Conn, e
|
|||||||
options = &ChainOptions{}
|
options = &ChainOptions{}
|
||||||
}
|
}
|
||||||
route, err := c.selectRouteFor(addr)
|
route, err := c.selectRouteFor(addr)
|
||||||
|
//log.Log("Connecting", addr, "using", route.Nodes()[0].Addr, "failcount", route.Nodes()[0].failCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -138,17 +142,12 @@ func (c *Chain) dialWithOptions(addr string, options *ChainOptions) (net.Conn, e
|
|||||||
return net.DialTimeout("tcp", addr, options.Timeout)
|
return net.DialTimeout("tcp", addr, options.Timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := route.getConn()
|
conn, err := route.getConn(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cc, err := route.LastNode().Client.Connect(conn, addr)
|
return conn, nil
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return cc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chain) resolve(addr string, resolver Resolver, hosts *Hosts) string {
|
func (c *Chain) resolve(addr string, resolver Resolver, hosts *Hosts) string {
|
||||||
@ -194,7 +193,7 @@ func (c *Chain) Conn(opts ...ChainOption) (conn net.Conn, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
conn, err = route.getConn()
|
conn, err = route.getConn("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Log(err)
|
log.Log(err)
|
||||||
continue
|
continue
|
||||||
@ -206,7 +205,7 @@ func (c *Chain) Conn(opts ...ChainOption) (conn net.Conn, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getConn obtains a connection to the last node of the chain.
|
// getConn obtains a connection to the last node of the chain.
|
||||||
func (c *Chain) getConn() (conn net.Conn, err error) {
|
func (c *Chain) getConn(addr string) (conn net.Conn, err error) {
|
||||||
if c.IsEmpty() {
|
if c.IsEmpty() {
|
||||||
err = ErrEmptyChain
|
err = ErrEmptyChain
|
||||||
return
|
return
|
||||||
@ -225,7 +224,10 @@ func (c *Chain) getConn() (conn net.Conn, err error) {
|
|||||||
node.MarkDead()
|
node.MarkDead()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.ResetDead()
|
|
||||||
|
if len(nodes) > 1 {
|
||||||
|
node.ResetDead() // don't reset the last node as we are going to check if it will connect successfully.
|
||||||
|
}
|
||||||
|
|
||||||
preNode := node
|
preNode := node
|
||||||
for _, node := range nodes[1:] {
|
for _, node := range nodes[1:] {
|
||||||
@ -242,13 +244,27 @@ func (c *Chain) getConn() (conn net.Conn, err error) {
|
|||||||
node.MarkDead()
|
node.MarkDead()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.ResetDead()
|
if len(nodes) > 1 {
|
||||||
|
node.ResetDead()
|
||||||
|
}
|
||||||
cn = cc
|
cn = cc
|
||||||
preNode = node
|
preNode = node
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = cn
|
conn = cn
|
||||||
|
if addr != "" {
|
||||||
|
var cc net.Conn
|
||||||
|
cc, err = node.Client.Connect(conn, addr)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(*net.OpError); ok {
|
||||||
|
node.MarkDead()
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
conn = cc
|
||||||
|
}
|
||||||
|
node.ResetDead()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
socks.go
4
socks.go
@ -215,9 +215,13 @@ func (c *socks5Connector) Connect(conn net.Conn, addr string) (net.Conn, error)
|
|||||||
)
|
)
|
||||||
|
|
||||||
cc := gosocks5.ClientConn(conn, selector)
|
cc := gosocks5.ClientConn(conn, selector)
|
||||||
|
|
||||||
|
conn.SetDeadline(time.Now().Add(time.Second * 5))
|
||||||
if err := cc.Handleshake(); err != nil {
|
if err := cc.Handleshake(); err != nil {
|
||||||
|
conn.SetDeadline(time.Time{})
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
conn.SetDeadline(time.Time{})
|
||||||
conn = cc
|
conn = cc
|
||||||
|
|
||||||
host, port, err := net.SplitHostPort(addr)
|
host, port, err := net.SplitHostPort(addr)
|
||||||
|
Loading…
Reference in New Issue
Block a user