Skip to content

Commit 60aaaa2

Browse files
some timeout tweaks
1 parent 5ac8830 commit 60aaaa2

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

gohpts.go

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
)
3434

3535
const (
36-
readTimeout time.Duration = 10 * time.Second
37-
writeTimeout time.Duration = 10 * time.Second
36+
readTimeout time.Duration = 3 * time.Second
37+
writeTimeout time.Duration = 3 * time.Second
3838
timeout time.Duration = 10 * time.Second
3939
hopTimeout time.Duration = 3 * time.Second
4040
flushTimeout time.Duration = 10 * time.Millisecond
@@ -46,6 +46,7 @@ const (
4646
var (
4747
supportedChainTypes = []string{"strict", "dynamic", "random", "round_robin"}
4848
SupportedTProxyModes = []string{"redirect", "tproxy"}
49+
errInvalidWrite = errors.New("invalid write result")
4950
)
5051

5152
// Hop-by-hop headers
@@ -476,7 +477,9 @@ func (p *proxyapp) handleTunnel(w http.ResponseWriter, r *http.Request) {
476477
w.WriteHeader(http.StatusServiceUnavailable)
477478
return
478479
}
479-
dstConn, err = sockDialer.Dial("tcp", r.Host)
480+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
481+
defer cancel()
482+
dstConn, err = sockDialer.(proxy.ContextDialer).DialContext(ctx, "tcp", r.Host)
480483
if err != nil {
481484
p.logger.Error().Err(err).Msgf("Failed connecting to %s", r.Host)
482485
http.Error(w, err.Error(), http.StatusServiceUnavailable)
@@ -513,9 +516,56 @@ func (p *proxyapp) handleTunnel(w http.ResponseWriter, r *http.Request) {
513516
wg.Wait()
514517
}
515518

516-
func (p *proxyapp) transfer(wg *sync.WaitGroup, destination io.Writer, source io.Reader, destName, srcName string) {
519+
func (p *proxyapp) copyWithTimeout(dst net.Conn, src net.Conn) (written int64, err error) {
520+
buf := make([]byte, 32*1024)
521+
for {
522+
er := src.SetReadDeadline(time.Now().Add(readTimeout))
523+
if er != nil {
524+
err = er
525+
break
526+
}
527+
nr, er := src.Read(buf)
528+
if nr > 0 {
529+
er := dst.SetWriteDeadline(time.Now().Add(writeTimeout))
530+
if er != nil {
531+
err = er
532+
break
533+
}
534+
nw, ew := dst.Write(buf[0:nr])
535+
if nw < 0 || nr < nw {
536+
nw = 0
537+
if ew == nil {
538+
ew = errInvalidWrite
539+
}
540+
}
541+
written += int64(nw)
542+
if ew != nil {
543+
if ne, ok := ew.(net.Error); ok && ne.Timeout() {
544+
err = ne
545+
break
546+
}
547+
}
548+
if nr != nw {
549+
err = io.ErrShortWrite
550+
break
551+
}
552+
}
553+
if er != nil {
554+
if ne, ok := err.(net.Error); ok && ne.Timeout() {
555+
err = er
556+
break
557+
}
558+
if er == io.EOF {
559+
break
560+
}
561+
}
562+
}
563+
return written, err
564+
}
565+
566+
func (p *proxyapp) transfer(wg *sync.WaitGroup, dst net.Conn, src net.Conn, destName, srcName string) {
517567
defer wg.Done()
518-
n, err := io.Copy(destination, source)
568+
n, err := p.copyWithTimeout(dst, src)
519569
if err != nil {
520570
p.logger.Error().Err(err).Msgf("Error during copy from %s to %s: %v", srcName, destName, err)
521571
}
@@ -718,7 +768,9 @@ func (ts *tproxyServer) handleConnection(srcConn net.Conn) {
718768
ts.pa.logger.Error().Err(err).Msg("[tproxy] Failed getting SOCKS5 client")
719769
return
720770
}
721-
dstConn, err = sockDialer.Dial("tcp", dst)
771+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
772+
defer cancel()
773+
dstConn, err = sockDialer.(proxy.ContextDialer).DialContext(ctx, "tcp", dst)
722774
if err != nil {
723775
ts.pa.logger.Error().Err(err).Msgf("[tproxy] Failed connecting to %s", dst)
724776
return
@@ -835,6 +887,7 @@ type Config struct {
835887
TProxyOnly string
836888
TProxyMode string
837889
}
890+
838891
type logWriter struct {
839892
}
840893

0 commit comments

Comments
 (0)