Better Timeout in Socks5 handshake

This commit is contained in:
NI
2019-09-03 21:40:57 +08:00
parent bf68b88919
commit 11d6a58a36

View File

@@ -18,6 +18,7 @@
package network package network
import ( import (
"context"
"net" "net"
"time" "time"
@@ -28,41 +29,30 @@ var (
emptyTime = time.Time{} emptyTime = time.Time{}
) )
type socks5Conn struct { type socks5Dial struct {
net.Conn net.Dialer
initialReadDeadline time.Time
} }
func (s *socks5Conn) SetDeadline(t time.Time) error { func (s socks5Dial) Dial(
s.initialReadDeadline = emptyTime network, address string) (net.Conn, error) {
conn, dErr := s.Dialer.Dial(network, address)
return s.Conn.SetDeadline(t) if dErr == nil {
conn.SetReadDeadline(time.Now().Add(s.Dialer.Timeout))
} }
func (s *socks5Conn) SetReadDeadline(t time.Time) error { return conn, dErr
s.initialReadDeadline = emptyTime
return s.Conn.SetReadDeadline(t)
} }
func (s *socks5Conn) SetWriteDeadline(t time.Time) error { func (s socks5Dial) DialContext(
s.initialReadDeadline = emptyTime ctx context.Context, network, address string) (net.Conn, error) {
conn, dErr := s.Dialer.DialContext(ctx, network, address)
return s.Conn.SetWriteDeadline(t) if dErr == nil {
conn.SetReadDeadline(time.Now().Add(s.Dialer.Timeout))
} }
func (s *socks5Conn) Read(b []byte) (int, error) { return conn, dErr
if s.initialReadDeadline != emptyTime {
s.Conn.SetReadDeadline(s.initialReadDeadline)
s.initialReadDeadline = emptyTime
defer s.Conn.SetReadDeadline(emptyTime)
}
rLen, rErr := s.Conn.Read(b)
return rLen, rErr
} }
// BuildSocks5Dial builds a Socks5 dialer // BuildSocks5Dial builds a Socks5 dialer
@@ -82,9 +72,11 @@ func BuildSocks5Dial(
address string, address string,
timeout time.Duration, timeout time.Duration,
) (net.Conn, error) { ) (net.Conn, error) {
dialCfg := net.Dialer{ dialCfg := socks5Dial{
Dialer: net.Dialer{
Timeout: timeout, Timeout: timeout,
Deadline: time.Now().Add(timeout), Deadline: time.Now().Add(timeout),
},
} }
dial, dialErr := proxy.SOCKS5("tcp", socks5Address, auth, &dialCfg) dial, dialErr := proxy.SOCKS5("tcp", socks5Address, auth, &dialCfg)
@@ -99,9 +91,8 @@ func BuildSocks5Dial(
return nil, dialErr return nil, dialErr
} }
return &socks5Conn{ dialConn.SetReadDeadline(emptyTime)
Conn: dialConn,
initialReadDeadline: dialCfg.Deadline, return dialConn, nil
}, nil
}, nil }, nil
} }