Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
Wrap handshake errors in a temporary net.Error().
Fixes bug #14135.
  • Loading branch information
Yawning committed Apr 3, 2015
1 parent 93bcaf4 commit e43b7d4ae09aaf10f0d544cf86da62bf1de3d74b
Showing with 40 additions and 16 deletions.
  1. +40 −16 socks.go
@@ -48,6 +48,21 @@ const (
// Put a sanity timeout on how long we wait for a SOCKS request.
const socksRequestTimeout = 5 * time.Second

// socksError wraps connection errors in a temporary net.Error interface.
type socksError string

func (e socksError) Error() string {
return string(e)
}

func (e socksError) Timeout() bool {
return false
}

func (e socksError) Temporary() bool {
return true
}

// SocksRequest describes a SOCKS request.
type SocksRequest struct {
// The endpoint requested by the client as a "host:port" string.
@@ -166,27 +181,35 @@ func (ln *SocksListener) Accept() (net.Conn, error) {
// }
// go handleConn(conn)
// }
func (ln *SocksListener) AcceptSocks() (*SocksConn, error) {
c, err := ln.Listener.Accept()
if err != nil {
func (ln *SocksListener) AcceptSocks() (conn *SocksConn, err error) {
conn = new(SocksConn)
if conn.Conn, err = ln.Listener.Accept(); err != nil {
return nil, err
}
conn := new(SocksConn)
conn.Conn = c
err = conn.SetDeadline(time.Now().Add(socksRequestTimeout))
if err != nil {
return nil, err

// All errors occur past this point net.Error or not, have absolutely
// nothing to do with the SocksListener or the Accept() call, and
// instead are errors generated by the handshake process. Thus, all
// errors that occur are wrapped in a net.Error implementation whos
// Temporary() always returns true.
defer func() {
if err != nil {
if conn != nil {
conn.Close()
conn = nil
}
err = socksError(err.Error())
}
}()

if err = conn.SetDeadline(time.Now().Add(socksRequestTimeout)); err != nil {
return
}
conn.Req, err = socks5Handshake(conn)
if err != nil {
conn.Close()
return nil, err
if conn.Req, err = socks5Handshake(conn); err != nil {
return
}
err = conn.SetDeadline(time.Time{})
if err != nil {
return nil, err
}
return conn, nil
return
}

// Returns "socks5", suitable to be included in a call to Cmethod.
@@ -501,4 +524,5 @@ func socksReadByteVerify(rw *bufio.ReadWriter, descr string, expected byte) erro
return nil
}

var _ net.Error = (socksError)("")
var _ net.Listener = (*SocksListener)(nil)

0 comments on commit e43b7d4

Please sign in to comment.