diff --git a/proxy/conn.go b/proxy/conn.go index 8b0837b..ab1d5d2 100644 --- a/proxy/conn.go +++ b/proxy/conn.go @@ -55,10 +55,24 @@ func Relay(left, right net.Conn) error { go func() { defer wg.Done() _, err1 = Copy(right, left) + if rc, ok := right.(interface { + CloseWrite() error + }); ok { + if e1 := rc.CloseWrite(); err1 == nil && e1 != io.EOF { + err1 = e1 + } + } right.SetReadDeadline(time.Now().Add(wait)) // unblock read on right }() _, err = Copy(left, right) + if lc, ok := left.(interface { + CloseWrite() error + }); ok { + if e := lc.CloseWrite(); err1 == nil && e != io.EOF { + err = e + } + } left.SetReadDeadline(time.Now().Add(wait)) // unblock read on left wg.Wait() diff --git a/proxy/ss/cipher/internal/shadowaead/conn.go b/proxy/ss/cipher/internal/shadowaead/conn.go index 2f0bb0f..266ea89 100644 --- a/proxy/ss/cipher/internal/shadowaead/conn.go +++ b/proxy/ss/cipher/internal/shadowaead/conn.go @@ -65,3 +65,23 @@ func (c *streamConn) Write(b []byte) (int, error) { } return c.w.Write(b) } + +func (c *streamConn) CloseWrite() error { + if conn, ok := c.Conn.(interface { + CloseWrite() error + }); ok { + return conn.CloseWrite() + } + + return nil +} + +func (c *streamConn) CloseRead() error { + if conn, ok := c.Conn.(interface { + CloseRead() error + }); ok { + return conn.CloseRead() + } + + return nil +} diff --git a/proxy/ss/cipher/internal/shadowstream/conn.go b/proxy/ss/cipher/internal/shadowstream/conn.go index fff77d3..f8e16f9 100644 --- a/proxy/ss/cipher/internal/shadowstream/conn.go +++ b/proxy/ss/cipher/internal/shadowstream/conn.go @@ -60,3 +60,23 @@ func (c *conn) Write(b []byte) (int, error) { } return c.w.Write(b) } + +func (c *conn) CloseWrite() error { + if conn, ok := c.Conn.(interface { + CloseWrite() error + }); ok { + return conn.CloseWrite() + } + + return nil +} + +func (c *conn) CloseRead() error { + if conn, ok := c.Conn.(interface { + CloseRead() error + }); ok { + return conn.CloseRead() + } + + return nil +}