From 96ba89462c0960dfbed2fd9c41edf4d6eb90aa95 Mon Sep 17 00:00:00 2001 From: Aleksandr Zaitsev Date: Sat, 21 Sep 2024 09:22:40 +0300 Subject: [PATCH] skip i/o timeout logs --- conn/conn.go | 33 +++++++++++++++++++++++++-------- gsocks5.go | 4 ++-- server/server.go | 9 +++++---- server/server_test.go | 27 ++++++++++++++++----------- 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/conn/conn.go b/conn/conn.go index f544983..4bcadb0 100644 --- a/conn/conn.go +++ b/conn/conn.go @@ -2,6 +2,7 @@ package conn import ( "context" + "errors" "fmt" "log" "net" @@ -25,22 +26,38 @@ func newIdleTimeoutConn(conn net.Conn, timeout time.Duration, logger *log.Logger // Read reads data from the connection. func (c *idleTimeoutConn) Read(b []byte) (int, error) { - if c.timeout > 0 { - if err := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)); err != nil { - c.logger.Printf("failed to set read deadline: %v", err) + var netErr net.Error + n, err := c.Conn.Read(b) + + if err != nil { + if errors.As(err, &netErr) && netErr.Timeout() { + c.logger.Printf("idleTimeoutConn read timeout from %s to %s", c.Conn.RemoteAddr(), c.Conn.LocalAddr()) + } + } else if c.timeout > 0 { + if deadlineErr := c.Conn.SetReadDeadline(time.Now().Add(c.timeout)); deadlineErr != nil { + c.logger.Printf("idleTimeoutConn failed to set read deadline: %v", deadlineErr) } } - return c.Conn.Read(b) + + return n, err } // Write writes data to the connection. func (c *idleTimeoutConn) Write(b []byte) (int, error) { - if c.timeout > 0 { - if err := c.Conn.SetWriteDeadline(time.Now().Add(c.timeout)); err != nil { - c.logger.Printf("failed to set write deadline: %v", err) + var netErr net.Error + n, err := c.Conn.Write(b) + + if err != nil { + if errors.As(err, &netErr) && netErr.Timeout() { + c.logger.Printf("idleTimeoutConn write timeout from %s to %s", c.Conn.RemoteAddr(), c.Conn.LocalAddr()) + } + } else if c.timeout > 0 { + if deadlineErr := c.Conn.SetWriteDeadline(time.Now().Add(c.timeout)); deadlineErr != nil { + c.logger.Printf("idleTimeoutConn failed to set write deadline: %v", deadlineErr) } } - return c.Conn.Write(b) + + return n, err } // Dial creates a new DialType. diff --git a/gsocks5.go b/gsocks5.go index 89f1fc1..5918868 100644 --- a/gsocks5.go +++ b/gsocks5.go @@ -47,10 +47,10 @@ func main() { debugMode bool connections uint32 = 1024 port uint16 = 1080 - timeoutIdle = 20 * time.Second + timeoutIdle = 30 * time.Second timeoutDNS = 5 * time.Second timeoutKeepAlive = 90 * time.Second - timeoutConn = 5 * time.Second + timeoutConn = 10 * time.Second ) defer func() { if r := recover(); r != nil { diff --git a/server/server.go b/server/server.go index aab176f..32e984e 100644 --- a/server/server.go +++ b/server/server.go @@ -7,6 +7,7 @@ import ( "log" "net" "os" + "strings" "sync" "time" @@ -132,6 +133,7 @@ func (s *Server) start(p *Params, connections <-chan net.Conn, semaphore <-chan } func (s *Server) handle(p *Params, conn net.Conn, semaphore <-chan struct{}) { + const skipError = "i/o timeout" var ( t = time.Now() client = conn.RemoteAddr().String() @@ -153,11 +155,10 @@ func (s *Server) handle(p *Params, conn net.Conn, semaphore <-chan struct{}) { }() if err = s.S.ServeConn(conn); err != nil { - var netErr net.Error - if errors.As(err, &netErr) && netErr.Timeout() { - s.logDebug.Printf("connection from %s is closed due to timeout [%T]: %v", client, err, err) + if errMsg := err.Error(); strings.HasSuffix(errMsg, skipError) { + s.logDebug.Printf("connection from %s is closed due to timeout: %v", client, err) } else { - s.logInfo.Printf("failed to serve connection from client %q: %v", client, err) + s.logInfo.Printf("failed to serve connection from client %q [%T]: %v", client, err, err) } } else { s.logDebug.Printf("connection served from %s during %v", client, time.Since(t)) diff --git a/server/server_test.go b/server/server_test.go index 557993d..d7e631d 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -14,16 +14,17 @@ import ( "github.com/z0rr0/gsocks5/conn" ) -const timeout = 200 * time.Millisecond +const timeout = 250 * time.Millisecond var logger = log.New(os.Stdout, "[test] ", log.LstdFlags|log.Lshortfile|log.Lmicroseconds) -func run(t *testing.T, s *Server, i, port int, isErr bool) (string, chan os.Signal) { +func run(t *testing.T, s *Server, i, port int, isErr bool, count uint32) (string, chan os.Signal) { params := &Params{ Addr: net.JoinHostPort("localhost", strconv.Itoa(port)), - Connections: 1, + Connections: count, Done: make(chan struct{}), Sigint: make(chan os.Signal), + Timeout: timeout, } go func() { @@ -48,21 +49,24 @@ func TestNew(t *testing.T) { cases := []struct { name string port int + count uint32 hosts []testHost err bool }{ - {name: "one", port: 1080, hosts: []testHost{{host: "github.com", port: 443}}}, + {name: "one", port: 1080, count: 1, hosts: []testHost{{host: "github.com", port: 443}}}, { - name: "two", - port: 1080, + name: "two", + port: 1080, + count: 2, hosts: []testHost{ {host: "github.com", port: 443}, {host: "leetcode.com", port: 443, close: true}, }, }, { - name: "three", - port: 1080, + name: "three", + port: 1080, + count: 3, hosts: []testHost{ {host: "github.com", port: 443, close: true}, {host: "leetcode.com", port: 443, close: true}, @@ -70,8 +74,9 @@ func TestNew(t *testing.T) { }, }, { - name: "many", - port: 1080, + name: "many", + port: 1080, + count: 10, hosts: []testHost{ {host: "github.com", port: 443, close: true}, {host: "github.com", port: 80}, @@ -93,7 +98,7 @@ func TestNew(t *testing.T) { tt.Errorf("case [%d] %s: unexpected error: %v", i, c.name, err) } - addr, sigint := run(tt, s, i, c.port, c.err) + addr, sigint := run(tt, s, i, c.port, c.err, c.count) defer close(sigint) if c.err {