diff --git a/common/baderror/baderror.go b/common/baderror/baderror.go index 1e9a207d..6cf581aa 100644 --- a/common/baderror/baderror.go +++ b/common/baderror/baderror.go @@ -1,6 +1,13 @@ package baderror -import "strings" +import ( + "context" + "io" + "net" + "strings" + + E "github.com/sagernet/sing/common/exceptions" +) func Contains(err error, msgList ...string) bool { for _, msg := range msgList { @@ -10,3 +17,46 @@ func Contains(err error, msgList ...string) bool { } return false } + +func WrapH2(err error) error { + if err == nil { + return nil + } + err = E.Unwrap(err) + if err == io.ErrUnexpectedEOF { + return io.EOF + } + if Contains(err, "client disconnected", "body closed by handler") { + return net.ErrClosed + } + return err +} + +func WrapGRPC(err error) error { + // grpc uses stupid internal error types + if err == nil { + return nil + } + if Contains(err, "EOF") { + return io.EOF + } + if Contains(err, "Canceled") { + return context.Canceled + } + if Contains(err, + "the client connection is closing", + "server closed the stream without sending trailers") { + return net.ErrClosed + } + return err +} + +func WrapQUIC(err error) error { + if err == nil { + return nil + } + if Contains(err, "canceled with error code 0") { + return net.ErrClosed + } + return err +} diff --git a/common/baderror/grpc.go b/common/baderror/grpc.go deleted file mode 100644 index 4e42cea4..00000000 --- a/common/baderror/grpc.go +++ /dev/null @@ -1,26 +0,0 @@ -package baderror - -import ( - "context" - "io" - "net" -) - -func WrapGRPC(err error) error { - // grpc uses stupid internal error types - if err == nil { - return nil - } - if Contains(err, "EOF") { - return io.EOF - } - if Contains(err, "Canceled") { - return context.Canceled - } - if Contains(err, - "the client connection is closing", - "server closed the stream without sending trailers") { - return net.ErrClosed - } - return err -} diff --git a/common/baderror/h2.go b/common/baderror/h2.go deleted file mode 100644 index f447b630..00000000 --- a/common/baderror/h2.go +++ /dev/null @@ -1,22 +0,0 @@ -package baderror - -import ( - "io" - "net" - - E "github.com/sagernet/sing/common/exceptions" -) - -func WrapH2(err error) error { - if err == nil { - return nil - } - err = E.Unwrap(err) - if err == io.ErrUnexpectedEOF { - return io.EOF - } - if Contains(err, "client disconnected", "body closed by handler") { - return net.ErrClosed - } - return err -} diff --git a/transport/hysteria/wrap.go b/transport/hysteria/wrap.go index f8df1b3b..f1155c4d 100644 --- a/transport/hysteria/wrap.go +++ b/transport/hysteria/wrap.go @@ -6,6 +6,7 @@ import ( "syscall" "github.com/sagernet/quic-go" + "github.com/sagernet/sing-box/common/baderror" "github.com/sagernet/sing/common" ) @@ -38,6 +39,16 @@ type StreamWrapper struct { quic.Stream } +func (s *StreamWrapper) Read(p []byte) (n int, err error) { + n, err = s.Stream.Read(p) + return n, baderror.WrapQUIC(err) +} + +func (s *StreamWrapper) Write(p []byte) (n int, err error) { + n, err = s.Stream.Write(p) + return n, baderror.WrapQUIC(err) +} + func (s *StreamWrapper) LocalAddr() net.Addr { return s.Conn.LocalAddr() } @@ -50,10 +61,6 @@ func (s *StreamWrapper) Upstream() any { return s.Stream } -func (s *StreamWrapper) ReaderReplaceable() bool { - return true -} - func (s *StreamWrapper) WriterReplaceable() bool { return true }