diff --git a/cli/portal/portal-v2board/main.go b/cli/portal/portal-v2board/main.go index a9c80aa..bcff7c4 100644 --- a/cli/portal/portal-v2board/main.go +++ b/cli/portal/portal-v2board/main.go @@ -15,11 +15,11 @@ import ( "github.com/sagernet/sing" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/acme" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" _ "github.com/sagernet/sing/common/log" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" - "github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/protocol/trojan" transTLS "github.com/sagernet/sing/transport/tls" "github.com/sirupsen/logrus" @@ -180,7 +180,7 @@ func (i *TrojanInstance) NewConnection(ctx context.Context, conn net.Conn, metad if err != nil { return err } - return rw.CopyConn(ctx, conn, destConn) + return bufio.CopyConn(ctx, conn, destConn) } func (i *TrojanInstance) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { @@ -191,7 +191,7 @@ func (i *TrojanInstance) NewPacketConnection(ctx context.Context, conn N.PacketC if err != nil { return err } - return N.CopyNetPacketConn(ctx, conn, udpConn) + return bufio.CopyNetPacketConn(ctx, conn, udpConn) } func (i *TrojanInstance) loopRequests() { diff --git a/cli/ss-local/main.go b/cli/ss-local/main.go index b87c963..888cf71 100644 --- a/cli/ss-local/main.go +++ b/cli/ss-local/main.go @@ -18,6 +18,7 @@ import ( "github.com/sagernet/sing" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/geoip" "github.com/sagernet/sing/common/geosite" @@ -324,7 +325,7 @@ func (c *client) NewConnection(ctx context.Context, conn net.Conn, metadata M.Me return E.Cause(err, "client handshake") } runtime.KeepAlive(_payload) - return rw.CopyConn(ctx, serverConn, conn) + return bufio.CopyConn(ctx, serverConn, conn) } func (c *client) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { @@ -334,7 +335,7 @@ func (c *client) NewPacketConnection(ctx context.Context, conn N.PacketConn, met return err } serverConn := c.method.DialPacketConn(udpConn) - return N.CopyPacketConn(ctx, serverConn, conn) + return bufio.CopyPacketConn(ctx, serverConn, conn) } func run(cmd *cobra.Command, flags *flags) { diff --git a/cli/ss-server/main.go b/cli/ss-server/main.go index 7202ff1..c328c23 100644 --- a/cli/ss-server/main.go +++ b/cli/ss-server/main.go @@ -14,12 +14,12 @@ import ( "github.com/sagernet/sing" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" _ "github.com/sagernet/sing/common/log" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/common/random" - "github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/protocol/shadowsocks" "github.com/sagernet/sing/protocol/shadowsocks/shadowaead" "github.com/sagernet/sing/protocol/shadowsocks/shadowaead_2022" @@ -191,7 +191,7 @@ func (s *server) NewConnection(ctx context.Context, conn net.Conn, metadata M.Me if err != nil { return err } - return rw.CopyConn(ctx, conn, destConn) + return bufio.CopyConn(ctx, conn, destConn) } func (s *server) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { @@ -200,7 +200,7 @@ func (s *server) NewPacketConnection(ctx context.Context, conn N.PacketConn, met if err != nil { return err } - return N.CopyNetPacketConn(ctx, conn, udpConn) + return bufio.CopyNetPacketConn(ctx, conn, udpConn) } func (s *server) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata M.Metadata) error { diff --git a/cli/trojan-local/main.go b/cli/trojan-local/main.go index e7b06e2..eae1099 100644 --- a/cli/trojan-local/main.go +++ b/cli/trojan-local/main.go @@ -17,12 +17,12 @@ import ( "github.com/sagernet/sing" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" _ "github.com/sagernet/sing/common/log" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/common/redir" - "github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/protocol/trojan" "github.com/sagernet/sing/transport/mixed" "github.com/sirupsen/logrus" @@ -317,7 +317,7 @@ func (c *client) NewConnection(ctx context.Context, conn net.Conn, metadata M.Me return E.Cause(err, "client handshake") } runtime.KeepAlive(_request) - return rw.CopyConn(ctx, clientConn, conn) + return bufio.CopyConn(ctx, clientConn, conn) } func (c *client) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { @@ -333,7 +333,7 @@ func (c *client) NewPacketConnection(ctx context.Context, conn N.PacketConn, met } return socks.CopyPacketConn(ctx, &trojan.PacketConn{Conn: tlsConn}, conn)*/ clientConn := trojan.NewClientPacketConn(tlsConn, c.key) - return N.CopyPacketConn(ctx, clientConn, conn) + return bufio.CopyPacketConn(ctx, clientConn, conn) } func (c *client) HandleError(err error) { diff --git a/cli/trojan-server/main.go b/cli/trojan-server/main.go index 07392f6..cc22962 100644 --- a/cli/trojan-server/main.go +++ b/cli/trojan-server/main.go @@ -14,11 +14,11 @@ import ( "github.com/sagernet/sing" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/acme" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" _ "github.com/sagernet/sing/common/log" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" - "github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/protocol/trojan" "github.com/sagernet/sing/transport/tcp" transTLS "github.com/sagernet/sing/transport/tls" @@ -197,7 +197,7 @@ func (s *server) NewConnection(ctx context.Context, conn net.Conn, metadata M.Me return err } logrus.Info("inbound TCP ", conn.RemoteAddr(), " ==> ", metadata.Destination) - return rw.CopyConn(ctx, conn, destConn) + return bufio.CopyConn(ctx, conn, destConn) } func (s *server) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { @@ -206,7 +206,7 @@ func (s *server) NewPacketConnection(ctx context.Context, conn N.PacketConn, met if err != nil { return err } - return N.CopyNetPacketConn(ctx, conn, udpConn) + return bufio.CopyNetPacketConn(ctx, conn, udpConn) } func (s *server) HandleError(err error) { diff --git a/cli/uot-local/main.go b/cli/uot-local/main.go index 45285bc..ea6e47b 100644 --- a/cli/uot-local/main.go +++ b/cli/uot-local/main.go @@ -10,12 +10,12 @@ import ( "github.com/sagernet/sing" "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" _ "github.com/sagernet/sing/common/log" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" "github.com/sagernet/sing/common/redir" - "github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/uot" "github.com/sagernet/sing/protocol/socks" "github.com/sagernet/sing/transport/mixed" @@ -108,7 +108,7 @@ func (c *localClient) NewConnection(ctx context.Context, conn net.Conn, metadata return err } - return rw.CopyConn(context.Background(), conn, upstream) + return bufio.CopyConn(context.Background(), conn, upstream) } func (c *localClient) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { @@ -119,7 +119,7 @@ func (c *localClient) NewPacketConnection(ctx context.Context, conn N.PacketConn return err } - return N.CopyPacketConn(ctx, conn, uot.NewClientConn(upstream)) + return bufio.CopyPacketConn(ctx, conn, uot.NewClientConn(upstream)) } func (c *localClient) OnError(err error) { diff --git a/common/rw/buffer.go b/common/bufio/buffer.go similarity index 96% rename from common/rw/buffer.go rename to common/bufio/buffer.go index 05cec16..dc49f87 100644 --- a/common/rw/buffer.go +++ b/common/bufio/buffer.go @@ -1,4 +1,4 @@ -package rw +package bufio import ( "io" @@ -7,6 +7,7 @@ import ( "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/rw" ) type CachedReader interface { @@ -124,7 +125,7 @@ func (w *BufferedWriter) Write(p []byte) (n int, err error) { } fd, err := common.TryFileDescriptor(w.Writer) if err == nil { - _, err = WriteV(fd, w.Buffer.Bytes(), p[n:]) + _, err = rw.WriteV(fd, w.Buffer.Bytes(), p[n:]) if err != nil { return } @@ -189,7 +190,7 @@ func (w *HeaderWriter) Write(p []byte) (n int, err error) { } fd, err := common.TryFileDescriptor(w.Writer) if err == nil { - _, err = WriteV(fd, w.Header.Bytes(), p) + _, err = rw.WriteV(fd, w.Header.Bytes(), p) if err != nil { return } diff --git a/common/bufio/conn.go b/common/bufio/conn.go new file mode 100644 index 0000000..f1358af --- /dev/null +++ b/common/bufio/conn.go @@ -0,0 +1,274 @@ +package bufio + +import ( + "context" + "io" + "net" + "os" + "runtime" + "time" + + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/buf" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" + "github.com/sagernet/sing/common/rw" + "github.com/sagernet/sing/common/task" +) + +type PacketConnStub struct{} + +func (s *PacketConnStub) RemoteAddr() net.Addr { + return &common.DummyAddr{} +} + +func (s *PacketConnStub) SetDeadline(t time.Time) error { + return os.ErrInvalid +} + +func (s *PacketConnStub) SetReadDeadline(t time.Time) error { + return os.ErrInvalid +} + +func (s *PacketConnStub) SetWriteDeadline(t time.Time) error { + return os.ErrInvalid +} + +func Copy(dst io.Writer, src io.Reader) (n int64, err error) { + if wt, ok := src.(io.WriterTo); ok { + return wt.WriteTo(dst) + } + if rt, ok := dst.(io.ReaderFrom); ok { + return rt.ReadFrom(src) + } + extendedSrc, srcExtended := src.(N.ExtendedReader) + extendedDst, dstExtended := dst.(N.ExtendedWriter) + if !srcExtended && !dstExtended { + _buffer := buf.StackNewMax() + defer runtime.KeepAlive(_buffer) + buffer := common.Dup(_buffer) + for { + buffer.FullReset() + _, err = buffer.ReadFrom(src) + if err != nil { + return + } + var cn int + cn, err = dst.Write(buffer.Bytes()) + n += int64(cn) + if err != nil { + return + } + } + } else if !srcExtended { + return CopyExtended(extendedDst, &ExtendedReaderWrapper{src}) + } else if !dstExtended { + return CopyExtended(&ExtendedWriterWrapper{dst}, extendedSrc) + } else { + return CopyExtended(extendedDst, extendedSrc) + } +} + +func CopyExtended(dst N.ExtendedWriter, src N.ExtendedReader) (n int64, err error) { + _buffer := buf.StackNewMax() + defer runtime.KeepAlive(_buffer) + buffer := common.Dup(_buffer) + data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) + for { + data.Reset() + err = src.ReadBuffer(data) + if err != nil { + return + } + dataLen := data.Len() + buffer.Resize(buf.ReversedHeader+data.Start(), dataLen) + err = dst.WriteBuffer(buffer) + if err != nil { + return + } + n += int64(dataLen) + } +} + +func CopyConn(ctx context.Context, conn net.Conn, dest net.Conn) error { + err := task.Run(ctx, func() error { + defer rw.CloseRead(conn) + defer rw.CloseWrite(dest) + return common.Error(Copy(dest, conn)) + }, func() error { + defer rw.CloseRead(dest) + defer rw.CloseWrite(conn) + return common.Error(Copy(conn, dest)) + }) + conn.Close() + dest.Close() + return err +} + +func CopyExtendedConn(ctx context.Context, conn N.ExtendedConn, dest N.ExtendedConn) error { + return task.Run(ctx, func() error { + defer rw.CloseRead(conn) + defer rw.CloseWrite(dest) + _buffer := buf.StackNewMax() + defer runtime.KeepAlive(_buffer) + buffer := common.Dup(_buffer) + data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) + for { + data.Reset() + _, err := data.ReadFrom(conn) + if err != nil { + return err + } + buffer.Resize(buf.ReversedHeader+data.Start(), data.Len()) + err = dest.WriteBuffer(buffer) + if err != nil { + return err + } + } + }, func() error { + defer rw.CloseRead(dest) + defer rw.CloseWrite(conn) + _buffer := buf.StackNewMax() + defer runtime.KeepAlive(_buffer) + buffer := common.Dup(_buffer) + data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) + for { + data.Reset() + _, err := data.ReadFrom(dest) + if err != nil { + return err + } + buffer.Resize(buf.ReversedHeader+data.Start(), data.Len()) + err = conn.WriteBuffer(buffer) + if err != nil { + return err + } + } + }) +} + +func CopyPacketConn(ctx context.Context, conn N.PacketConn, dest N.PacketConn) error { + defer common.Close(conn, dest) + return task.Run(ctx, func() error { + _buffer := buf.StackNewMax() + defer runtime.KeepAlive(_buffer) + buffer := common.Dup(_buffer) + data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) + for { + data.FullReset() + destination, err := conn.ReadPacket(data) + if err != nil { + return err + } + buffer.Resize(buf.ReversedHeader+data.Start(), data.Len()) + err = dest.WritePacket(buffer, destination) + if err != nil { + return err + } + } + }, func() error { + _buffer := buf.StackNewMax() + defer runtime.KeepAlive(_buffer) + buffer := common.Dup(_buffer) + data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) + for { + data.FullReset() + destination, err := dest.ReadPacket(data) + if err != nil { + return err + } + buffer.Resize(buf.ReversedHeader+data.Start(), data.Len()) + err = conn.WritePacket(buffer, destination) + if err != nil { + return err + } + } + }) +} + +func CopyNetPacketConn(ctx context.Context, conn N.PacketConn, dest net.PacketConn) error { + if udpConn, ok := dest.(*net.UDPConn); ok { + return CopyPacketConn(ctx, conn, &UDPConnWrapper{udpConn}) + } else { + return CopyPacketConn(ctx, conn, &PacketConnWrapper{dest}) + } +} + +type UDPConnWrapper struct { + *net.UDPConn +} + +func (w *UDPConnWrapper) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { + n, addr, err := w.ReadFromUDPAddrPort(buffer.FreeBytes()) + if err != nil { + return M.Socksaddr{}, err + } + buffer.Truncate(n) + return M.SocksaddrFromNetIP(addr), nil +} + +func (w *UDPConnWrapper) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { + if destination.Family().IsFqdn() { + udpAddr, err := net.ResolveUDPAddr("udp", destination.String()) + if err != nil { + return err + } + return common.Error(w.UDPConn.WriteTo(buffer.Bytes(), udpAddr)) + } + return common.Error(w.UDPConn.WriteToUDP(buffer.Bytes(), destination.UDPAddr())) +} + +type PacketConnWrapper struct { + net.PacketConn +} + +func (p *PacketConnWrapper) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { + _, addr, err := buffer.ReadPacketFrom(p) + if err != nil { + return M.Socksaddr{}, err + } + return M.SocksaddrFromNet(addr), err +} + +func (p *PacketConnWrapper) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { + return common.Error(p.WriteTo(buffer.Bytes(), destination.UDPAddr())) +} + +type BindPacketConn struct { + net.PacketConn + Addr net.Addr +} + +func (c *BindPacketConn) Read(b []byte) (n int, err error) { + n, _, err = c.ReadFrom(b) + return +} + +func (c *BindPacketConn) Write(b []byte) (n int, err error) { + return c.WriteTo(b, c.Addr) +} + +func (c *BindPacketConn) RemoteAddr() net.Addr { + return c.Addr +} + +type ExtendedReaderWrapper struct { + io.Reader +} + +func (r *ExtendedReaderWrapper) ReadBuffer(buffer *buf.Buffer) error { + n, err := r.Read(buffer.FreeBytes()) + if err != nil { + return err + } + buffer.Truncate(n) + return nil +} + +type ExtendedWriterWrapper struct { + io.Writer +} + +func (w *ExtendedWriterWrapper) WriteBuffer(buffer *buf.Buffer) error { + return common.Error(w.Write(buffer.Bytes())) +} diff --git a/common/network/conn.go b/common/network/conn.go index 3da10c2..549075f 100644 --- a/common/network/conn.go +++ b/common/network/conn.go @@ -2,15 +2,12 @@ package network import ( "context" + "io" "net" - "os" - "runtime" "time" - "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" M "github.com/sagernet/sing/common/metadata" - "github.com/sagernet/sing/common/task" ) type PacketReader interface { @@ -32,6 +29,22 @@ type PacketConn interface { SetWriteDeadline(t time.Time) error } +type ExtendedReader interface { + io.Reader + ReadBuffer(buffer *buf.Buffer) error +} + +type ExtendedWriter interface { + io.Writer + WriteBuffer(buffer *buf.Buffer) error +} + +type ExtendedConn interface { + ExtendedReader + ExtendedWriter + net.Conn +} + type NetPacketConn interface { net.PacketConn PacketConn @@ -44,126 +57,3 @@ type UDPHandler interface { type UDPConnectionHandler interface { NewPacketConnection(ctx context.Context, conn PacketConn, metadata M.Metadata) error } - -type PacketConnStub struct{} - -func (s *PacketConnStub) RemoteAddr() net.Addr { - return &common.DummyAddr{} -} - -func (s *PacketConnStub) SetDeadline(t time.Time) error { - return os.ErrInvalid -} - -func (s *PacketConnStub) SetReadDeadline(t time.Time) error { - return os.ErrInvalid -} - -func (s *PacketConnStub) SetWriteDeadline(t time.Time) error { - return os.ErrInvalid -} - -func CopyPacketConn(ctx context.Context, conn PacketConn, dest PacketConn) error { - defer common.Close(conn, dest) - return task.Run(ctx, func() error { - _buffer := buf.StackNewMax() - defer runtime.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) - for { - data.FullReset() - destination, err := conn.ReadPacket(data) - if err != nil { - return err - } - buffer.Resize(buf.ReversedHeader+data.Start(), data.Len()) - err = dest.WritePacket(buffer, destination) - if err != nil { - return err - } - } - }, func() error { - _buffer := buf.StackNewMax() - defer runtime.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - data := buffer.Cut(buf.ReversedHeader, buf.ReversedHeader) - for { - data.FullReset() - destination, err := dest.ReadPacket(data) - if err != nil { - return err - } - buffer.Resize(buf.ReversedHeader+data.Start(), data.Len()) - err = conn.WritePacket(buffer, destination) - if err != nil { - return err - } - } - }) -} - -func CopyNetPacketConn(ctx context.Context, conn PacketConn, dest net.PacketConn) error { - if udpConn, ok := dest.(*net.UDPConn); ok { - return CopyPacketConn(ctx, conn, &UDPConnWrapper{udpConn}) - } else { - return CopyPacketConn(ctx, conn, &PacketConnWrapper{dest}) - } -} - -type UDPConnWrapper struct { - *net.UDPConn -} - -func (w *UDPConnWrapper) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { - n, addr, err := w.ReadFromUDPAddrPort(buffer.FreeBytes()) - if err != nil { - return M.Socksaddr{}, err - } - buffer.Truncate(n) - return M.SocksaddrFromNetIP(addr), nil -} - -func (w *UDPConnWrapper) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { - if destination.Family().IsFqdn() { - udpAddr, err := net.ResolveUDPAddr("udp", destination.String()) - if err != nil { - return err - } - return common.Error(w.UDPConn.WriteTo(buffer.Bytes(), udpAddr)) - } - return common.Error(w.UDPConn.WriteToUDP(buffer.Bytes(), destination.UDPAddr())) -} - -type PacketConnWrapper struct { - net.PacketConn -} - -func (p *PacketConnWrapper) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { - _, addr, err := buffer.ReadPacketFrom(p) - if err != nil { - return M.Socksaddr{}, err - } - return M.SocksaddrFromNet(addr), err -} - -func (p *PacketConnWrapper) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { - return common.Error(p.WriteTo(buffer.Bytes(), destination.UDPAddr())) -} - -type BindPacketConn struct { - net.PacketConn - Addr net.Addr -} - -func (c *BindPacketConn) Read(b []byte) (n int, err error) { - n, _, err = c.ReadFrom(b) - return -} - -func (c *BindPacketConn) Write(b []byte) (n int, err error) { - return c.WriteTo(b, c.Addr) -} - -func (c *BindPacketConn) RemoteAddr() net.Addr { - return c.Addr -} diff --git a/common/rw/copy.go b/common/rw/copy.go deleted file mode 100644 index f541b20..0000000 --- a/common/rw/copy.go +++ /dev/null @@ -1,95 +0,0 @@ -package rw - -import ( - "context" - "io" - "net" - "runtime" - - "github.com/sagernet/sing/common" - "github.com/sagernet/sing/common/buf" - "github.com/sagernet/sing/common/task" -) - -func CopyConn(ctx context.Context, conn net.Conn, dest net.Conn) error { - if pc, inPc := conn.(net.PacketConn); inPc { - if destPc, outPc := dest.(net.PacketConn); outPc { - return CopyPacketConn(ctx, pc, destPc) - } - } - - err := task.Run(ctx, func() error { - defer CloseRead(conn) - defer CloseWrite(dest) - return common.Error(Copy(dest, conn)) - }, func() error { - defer CloseRead(dest) - defer CloseWrite(conn) - return common.Error(Copy(conn, dest)) - }) - conn.Close() - dest.Close() - return err -} - -func Copy(dst io.Writer, src io.Reader) (n int64, err error) { - if wt, ok := src.(io.WriterTo); ok { - return wt.WriteTo(dst) - } - if rt, ok := dst.(io.ReaderFrom); ok { - return rt.ReadFrom(src) - } - _buffer := buf.StackNew() - defer runtime.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - for { - buffer.Reset() - _, err = buffer.ReadFrom(src) - if err != nil { - break - } - var cn int - cn, err = dst.Write(buffer.Bytes()) - if err != nil { - return - } - n += int64(cn) - } - return -} - -func CopyPacketConn(ctx context.Context, conn net.PacketConn, outPacketConn net.PacketConn) error { - return task.Run(ctx, func() error { - _buffer := buf.With(make([]byte, buf.UDPBufferSize)) - defer runtime.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - for { - n, addr, err := conn.ReadFrom(buffer.FreeBytes()) - if err != nil { - return err - } - buffer.Truncate(n) - _, err = outPacketConn.WriteTo(buffer.Bytes(), addr) - if err != nil { - return err - } - buffer.FullReset() - } - }, func() error { - _buffer := buf.With(make([]byte, buf.UDPBufferSize)) - defer runtime.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - for { - n, addr, err := outPacketConn.ReadFrom(buffer.FreeBytes()) - if err != nil { - return err - } - buffer.Truncate(n) - _, err = conn.WriteTo(buffer.Bytes(), addr) - if err != nil { - return err - } - buffer.FullReset() - } - }) -} diff --git a/protocol/shadowsocks/shadowaead_2022/relay.go b/protocol/shadowsocks/shadowaead_2022/relay.go index b05c52e..a2883d1 100644 --- a/protocol/shadowsocks/shadowaead_2022/relay.go +++ b/protocol/shadowsocks/shadowaead_2022/relay.go @@ -12,11 +12,11 @@ import ( "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio" "github.com/sagernet/sing/common/cache" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" - "github.com/sagernet/sing/common/rw" "github.com/sagernet/sing/common/udpnat" "github.com/sagernet/sing/protocol/shadowsocks" "github.com/sagernet/sing/protocol/shadowsocks/shadowaead" @@ -163,7 +163,7 @@ func (s *Relay[U]) newConnection(ctx context.Context, conn net.Conn, metadata M. } metadata.Protocol = "shadowsocks-relay" metadata.Destination = s.uDestination[user] - conn = &rw.BufferedConn{ + conn = &bufio.BufferedConn{ Conn: conn, Buffer: requestHeader, } diff --git a/transport/mixed/listener.go b/transport/mixed/listener.go index c99cd10..dfe9beb 100644 --- a/transport/mixed/listener.go +++ b/transport/mixed/listener.go @@ -1,7 +1,7 @@ package mixed import ( - "bufio" + std_bufio "bufio" "context" "io" "net" @@ -14,6 +14,7 @@ import ( "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" @@ -66,7 +67,7 @@ func (l *Listener) NewConnection(ctx context.Context, conn net.Conn, metadata M. return socks.HandleConnection0(ctx, conn, headerType, l.authenticator, l.handler, metadata) } - reader := bufio.NewReader(&rw.BufferedReader{ + reader := std_bufio.NewReader(&bufio.BufferedReader{ Reader: conn, Buffer: buf.As([]byte{headerType}), }) @@ -107,7 +108,7 @@ func (l *Listener) NewConnection(ctx context.Context, conn net.Conn, metadata M. return err } - conn = &rw.BufferedConn{ + conn = &bufio.BufferedConn{ Conn: conn, Buffer: buffer, }