From c68251b6d0592efd8b0d9e947a218fb2761ee7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 3 Jul 2023 08:21:04 +0800 Subject: [PATCH] Deprecate stack buffer --- common/buf/buffer.go | 34 ++------ common/buf/hex.go | 9 -- common/buf/pool.go | 43 +--------- common/buf/ptr.go | 34 -------- common/buf/ptr_go120.go | 34 -------- common/bufio/copy.go | 59 +------------ common/bufio/once.go | 127 ---------------------------- common/bufio/vectorised.go | 4 +- common/cond.go | 16 ++-- common/exceptions/cause.go | 3 - common/unsafe_default.go | 10 --- common/unsafe_disable.go | 5 -- common/uot/conn.go | 8 +- common/uot/server.go | 9 +- protocol/socks/packet.go | 4 +- protocol/socks/packet_vectorised.go | 4 +- protocol/socks/socks4/protocol.go | 8 +- protocol/socks/socks5/protocol.go | 16 +--- 18 files changed, 28 insertions(+), 399 deletions(-) delete mode 100644 common/buf/hex.go delete mode 100644 common/buf/ptr.go delete mode 100644 common/buf/ptr_go120.go delete mode 100644 common/bufio/once.go delete mode 100644 common/unsafe_default.go delete mode 100644 common/unsafe_disable.go diff --git a/common/buf/buffer.go b/common/buf/buffer.go index 10fa709..c374147 100644 --- a/common/buf/buffer.go +++ b/common/buf/buffer.go @@ -54,41 +54,19 @@ func NewSize(size int) *Buffer { } } +// Deprecated: use New instead. func StackNew() *Buffer { - if common.UnsafeBuffer { - return &Buffer{ - data: make([]byte, BufferSize), - start: ReversedHeader, - end: ReversedHeader, - } - } else { - return New() - } + return New() } +// Deprecated: use NewPacket instead. func StackNewPacket() *Buffer { - if common.UnsafeBuffer { - return &Buffer{ - data: make([]byte, UDPBufferSize), - start: ReversedHeader, - end: ReversedHeader, - } - } else { - return NewPacket() - } + return NewPacket() } +// Deprecated: use NewSize instead. func StackNewSize(size int) *Buffer { - if size == 0 { - return &Buffer{} - } - if common.UnsafeBuffer { - return &Buffer{ - data: Make(size), - } - } else { - return NewSize(size) - } + return NewSize(size) } func As(data []byte) *Buffer { diff --git a/common/buf/hex.go b/common/buf/hex.go deleted file mode 100644 index ca54f67..0000000 --- a/common/buf/hex.go +++ /dev/null @@ -1,9 +0,0 @@ -package buf - -import "encoding/hex" - -func EncodeHexString(src []byte) string { - dst := Make(hex.EncodedLen(len(src))) - hex.Encode(dst, src) - return string(dst) -} diff --git a/common/buf/pool.go b/common/buf/pool.go index a729989..37f1232 100644 --- a/common/buf/pool.go +++ b/common/buf/pool.go @@ -11,46 +11,7 @@ func Put(buf []byte) error { return DefaultAllocator.Put(buf) } +// Deprecated: use array instead. func Make(size int) []byte { - if size == 0 { - return nil - } - var buffer []byte - switch { - case size <= 2: - buffer = make([]byte, 2) - case size <= 4: - buffer = make([]byte, 4) - case size <= 8: - buffer = make([]byte, 8) - case size <= 16: - buffer = make([]byte, 16) - case size <= 32: - buffer = make([]byte, 32) - case size <= 64: - buffer = make([]byte, 64) - case size <= 128: - buffer = make([]byte, 128) - case size <= 256: - buffer = make([]byte, 256) - case size <= 512: - buffer = make([]byte, 512) - case size <= 1024: - buffer = make([]byte, 1024) - case size <= 2048: - buffer = make([]byte, 2048) - case size <= 4096: - buffer = make([]byte, 4096) - case size <= 8192: - buffer = make([]byte, 8192) - case size <= 16384: - buffer = make([]byte, 16384) - case size <= 32768: - buffer = make([]byte, 32768) - case size <= 65535: - buffer = make([]byte, 65535) - default: - return make([]byte, size) - } - return buffer[:size] + return make([]byte, size) } diff --git a/common/buf/ptr.go b/common/buf/ptr.go deleted file mode 100644 index 60e8fcf..0000000 --- a/common/buf/ptr.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build !disable_unsafe && go1.21 - -package buf - -import ( - "unsafe" - - "github.com/sagernet/sing/common" -) - -type dbgVar struct { - name string - value *int32 -} - -//go:linkname dbgvars runtime.dbgvars -var dbgvars any - -// go.info.runtime.dbgvars: relocation target go.info.[]github.com/sagernet/sing/common/buf.dbgVar not defined -// var dbgvars []dbgVar - -func init() { - if !common.UnsafeBuffer { - return - } - debugVars := *(*[]*dbgVar)(unsafe.Pointer(&dbgvars)) - for _, v := range debugVars { - if v.name == "invalidptr" { - *v.value = 0 - return - } - } - panic("can't disable invalidptr") -} diff --git a/common/buf/ptr_go120.go b/common/buf/ptr_go120.go deleted file mode 100644 index 575c723..0000000 --- a/common/buf/ptr_go120.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build !disable_unsafe && !go1.21 - -package buf - -import ( - "unsafe" - - "github.com/sagernet/sing/common" -) - -type dbgVar struct { - name string - value *int32 -} - -//go:linkname dbgvars runtime.dbgvars -var dbgvars any - -// go.info.runtime.dbgvars: relocation target go.info.[]github.com/sagernet/sing/common/buf.dbgVar not defined -// var dbgvars []dbgVar - -func init() { - if !common.UnsafeBuffer { - return - } - debugVars := *(*[]dbgVar)(unsafe.Pointer(&dbgvars)) - for _, v := range debugVars { - if v.name == "invalidptr" { - *v.value = 0 - return - } - } - panic("can't disable invalidptr") -} diff --git a/common/bufio/copy.go b/common/bufio/copy.go index c0ff6dd..ea279eb 100644 --- a/common/bufio/copy.go +++ b/common/bufio/copy.go @@ -71,20 +71,7 @@ func CopyExtended(originDestination io.Writer, destination N.ExtendedWriter, sou return } } - if !common.UnsafeBuffer || N.IsUnsafeWriter(destination) { - return CopyExtendedWithPool(originDestination, destination, source, readCounters, writeCounters) - } - bufferSize := N.CalculateMTU(source, destination) - if bufferSize > 0 { - bufferSize += headroom - } else { - bufferSize = buf.BufferSize - } - _buffer := buf.StackNewSize(bufferSize) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - defer buffer.Release() - return CopyExtendedBuffer(originDestination, destination, source, buffer, readCounters, writeCounters) + return CopyExtendedWithPool(originDestination, destination, source, readCounters, writeCounters) } func CopyExtendedBuffer(originDestination io.Writer, destination N.ExtendedWriter, source N.ExtendedReader, buffer *buf.Buffer, readCounters []N.CountFunc, writeCounters []N.CountFunc) (n int64, err error) { @@ -291,49 +278,7 @@ func CopyPacket(destinationConn N.PacketWriter, source N.PacketReader) (n int64, return } } - if N.IsUnsafeWriter(destinationConn) { - return CopyPacketWithPool(destinationConn, source, readCounters, writeCounters) - } - bufferSize := N.CalculateMTU(source, destinationConn) - if bufferSize > 0 { - bufferSize += headroom - } else { - bufferSize = buf.UDPBufferSize - } - _buffer := buf.StackNewSize(bufferSize) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) - defer buffer.Release() - buffer.IncRef() - defer buffer.DecRef() - var destination M.Socksaddr - var notFirstTime bool - readBufferRaw := buffer.Slice() - readBuffer := buf.With(readBufferRaw[:len(readBufferRaw)-rearHeadroom]) - for { - readBuffer.Resize(frontHeadroom, 0) - destination, err = source.ReadPacket(readBuffer) - if err != nil { - if !notFirstTime { - err = N.HandshakeFailure(destinationConn, err) - } - return - } - dataLen := readBuffer.Len() - buffer.Resize(readBuffer.Start(), dataLen) - err = destinationConn.WritePacket(buffer, destination) - if err != nil { - return - } - n += int64(dataLen) - for _, counter := range readCounters { - counter(int64(dataLen)) - } - for _, counter := range writeCounters { - counter(int64(dataLen)) - } - notFirstTime = true - } + return CopyPacketWithPool(destinationConn, source, readCounters, writeCounters) } func CopyPacketWithSrcBuffer(destinationConn N.PacketWriter, source N.ThreadSafePacketReader, readCounters []N.CountFunc, writeCounters []N.CountFunc) (n int64, err error) { diff --git a/common/bufio/once.go b/common/bufio/once.go deleted file mode 100644 index 5bfd0aa..0000000 --- a/common/bufio/once.go +++ /dev/null @@ -1,127 +0,0 @@ -package bufio - -import ( - "io" - - "github.com/sagernet/sing/common" - "github.com/sagernet/sing/common/buf" - N "github.com/sagernet/sing/common/network" -) - -func CopyTimes(dst io.Writer, src io.Reader, times int) (n int64, err error) { - return CopyExtendedTimes(NewExtendedWriter(N.UnwrapWriter(dst)), NewExtendedReader(N.UnwrapReader(src)), times) -} - -func CopyExtendedTimes(dst N.ExtendedWriter, src N.ExtendedReader, times int) (n int64, err error) { - frontHeadroom := N.CalculateFrontHeadroom(dst) - rearHeadroom := N.CalculateRearHeadroom(dst) - bufferSize := N.CalculateMTU(src, dst) - if bufferSize > 0 { - bufferSize += frontHeadroom + rearHeadroom - } else { - bufferSize = buf.BufferSize - } - dstUnsafe := N.IsUnsafeWriter(dst) - var buffer *buf.Buffer - if !dstUnsafe { - _buffer := buf.StackNewSize(bufferSize) - defer common.KeepAlive(_buffer) - buffer = common.Dup(_buffer) - defer buffer.Release() - buffer.IncRef() - defer buffer.DecRef() - } - notFirstTime := true - for i := 0; i < times; i++ { - if dstUnsafe { - buffer = buf.NewSize(bufferSize) - } - readBufferRaw := buffer.Slice() - readBuffer := buf.With(readBufferRaw[:cap(readBufferRaw)-rearHeadroom]) - readBuffer.Resize(frontHeadroom, 0) - err = src.ReadBuffer(readBuffer) - if err != nil { - buffer.Release() - if !notFirstTime { - err = N.HandshakeFailure(dst, err) - } - return - } - dataLen := readBuffer.Len() - buffer.Resize(readBuffer.Start(), dataLen) - err = dst.WriteBuffer(buffer) - if err != nil { - buffer.Release() - return - } - n += int64(dataLen) - notFirstTime = true - } - return -} - -type ReadFromWriter interface { - io.ReaderFrom - io.Writer -} - -func ReadFrom0(readerFrom ReadFromWriter, reader io.Reader) (n int64, err error) { - n, err = CopyTimes(readerFrom, reader, 1) - if err != nil { - return - } - var rn int64 - rn, err = readerFrom.ReadFrom(reader) - if err != nil { - return - } - n += rn - return -} - -func ReadFromN(readerFrom ReadFromWriter, reader io.Reader, times int) (n int64, err error) { - n, err = CopyTimes(readerFrom, reader, times) - if err != nil { - return - } - var rn int64 - rn, err = readerFrom.ReadFrom(reader) - if err != nil { - return - } - n += rn - return -} - -type WriteToReader interface { - io.WriterTo - io.Reader -} - -func WriteTo0(writerTo WriteToReader, writer io.Writer) (n int64, err error) { - n, err = CopyTimes(writer, writerTo, 1) - if err != nil { - return - } - var wn int64 - wn, err = writerTo.WriteTo(writer) - if err != nil { - return - } - n += wn - return -} - -func WriteToN(writerTo WriteToReader, writer io.Writer, times int) (n int64, err error) { - n, err = CopyTimes(writer, writerTo, times) - if err != nil { - return - } - var wn int64 - wn, err = writerTo.WriteTo(writer) - if err != nil { - return - } - n += wn - return -} diff --git a/common/bufio/vectorised.go b/common/bufio/vectorised.go index ef875fd..bc6c623 100644 --- a/common/bufio/vectorised.go +++ b/common/bufio/vectorised.go @@ -74,9 +74,7 @@ func (w *BufferedVectorisedWriter) WriteVectorised(buffers []*buf.Buffer) error if bufferLen > 65535 { bufferBytes = make([]byte, bufferLen) } else { - _buffer := buf.StackNewSize(bufferLen) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(bufferLen) defer buffer.Release() bufferBytes = buffer.FreeBytes() } diff --git a/common/cond.go b/common/cond.go index 24458a5..81843dd 100644 --- a/common/cond.go +++ b/common/cond.go @@ -159,20 +159,14 @@ func IndexIndexed[T any](arr []T, block func(index int, it T) bool) int { //go:norace func Dup[T any](obj T) T { - if UnsafeBuffer { - pointer := uintptr(unsafe.Pointer(&obj)) - //nolint:staticcheck - //goland:noinspection GoVetUnsafePointer - return *(*T)(unsafe.Pointer(pointer)) - } else { - return obj - } + pointer := uintptr(unsafe.Pointer(&obj)) + //nolint:staticcheck + //goland:noinspection GoVetUnsafePointer + return *(*T)(unsafe.Pointer(pointer)) } func KeepAlive(obj any) { - if UnsafeBuffer { - runtime.KeepAlive(obj) - } + runtime.KeepAlive(obj) } func Uniq[T comparable](arr []T) []T { diff --git a/common/exceptions/cause.go b/common/exceptions/cause.go index 27211f2..fe7adf3 100644 --- a/common/exceptions/cause.go +++ b/common/exceptions/cause.go @@ -6,9 +6,6 @@ type causeError struct { } func (e *causeError) Error() string { - if e.cause == nil { - return e.message - } return e.message + ": " + e.cause.Error() } diff --git a/common/unsafe_default.go b/common/unsafe_default.go deleted file mode 100644 index 3f3952d..0000000 --- a/common/unsafe_default.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !unsafe_buffer && !disable_unsafe_buffer - -package common - -import "runtime" - -// net/*Conn in windows keeps the buffer pointer passed in during io operations, so we disable it by default. -// https://github.com/golang/go/blob/4068be56ce7721a3d75606ea986d11e9ca27077a/src/internal/poll/fd_windows.go#L876 - -const UnsafeBuffer = runtime.GOOS != "windows" diff --git a/common/unsafe_disable.go b/common/unsafe_disable.go deleted file mode 100644 index 5795b0f..0000000 --- a/common/unsafe_disable.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build disable_unsafe_buffer - -package common - -const UnsafeBuffer = false diff --git a/common/uot/conn.go b/common/uot/conn.go index 7bc3fb8..81382a4 100644 --- a/common/uot/conn.go +++ b/common/uot/conn.go @@ -75,9 +75,7 @@ func (c *Conn) WriteTo(p []byte, addr net.Addr) (n int, err error) { if c.writer == nil { bufferLen += len(p) } - _buffer := buf.StackNewSize(bufferLen) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(bufferLen) defer buffer.Release() if !c.isConnect { common.Must(AddrParser.WriteAddrPort(buffer, destination)) @@ -124,9 +122,7 @@ func (c *Conn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { if c.writer == nil { headerLen += buffer.Len() } - _header := buf.StackNewSize(headerLen) - defer common.KeepAlive(_header) - header := common.Dup(_header) + header := buf.NewSize(headerLen) defer header.Release() if !c.isConnect { common.Must(AddrParser.WriteAddrPort(header, destination)) diff --git a/common/uot/server.go b/common/uot/server.go index b620cce..78cfa6d 100644 --- a/common/uot/server.go +++ b/common/uot/server.go @@ -5,7 +5,6 @@ import ( "io" "net" - "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" M "github.com/sagernet/sing/common/metadata" ) @@ -53,9 +52,7 @@ func (c *ServerConn) loopInput() { c.isConnect = request.IsConnect c.destination = request.Destination } - _buffer := buf.StackNew() - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewPacket() defer buffer.Release() for { var destination M.Socksaddr @@ -95,9 +92,7 @@ func (c *ServerConn) loopInput() { //warn:unsafe func (c *ServerConn) loopOutput() { - _buffer := buf.StackNew() - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewPacket() defer buffer.Release() for { buffer.FullReset() diff --git a/protocol/socks/packet.go b/protocol/socks/packet.go index 08028b0..555ee79 100644 --- a/protocol/socks/packet.go +++ b/protocol/socks/packet.go @@ -64,9 +64,7 @@ func (c *AssociatePacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err erro //warn:unsafe func (c *AssociatePacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { destination := M.SocksaddrFromNet(addr) - _buffer := buf.StackNewSize(3 + M.SocksaddrSerializer.AddrPortLen(destination) + len(p)) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(3 + M.SocksaddrSerializer.AddrPortLen(destination) + len(p)) defer buffer.Release() common.Must(buffer.WriteZeroN(3)) err = M.SocksaddrSerializer.WriteAddrPort(buffer, destination) diff --git a/protocol/socks/packet_vectorised.go b/protocol/socks/packet_vectorised.go index 78bf918..12684cc 100644 --- a/protocol/socks/packet_vectorised.go +++ b/protocol/socks/packet_vectorised.go @@ -40,9 +40,7 @@ func NewVectorisedAssociateConn(conn net.Conn, writer N.VectorisedWriter, remote } func (v *VectorisedAssociatePacketConn) WriteVectorisedPacket(buffers []*buf.Buffer, destination M.Socksaddr) error { - _header := buf.StackNewSize(3 + M.SocksaddrSerializer.AddrPortLen(destination)) - defer common.KeepAlive(_header) - header := common.Dup(_header) + header := buf.NewSize(3 + M.SocksaddrSerializer.AddrPortLen(destination)) defer header.Release() common.Must(header.WriteZeroN(3)) common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination)) diff --git a/protocol/socks/socks4/protocol.go b/protocol/socks/socks4/protocol.go index f5c8f7e..8b3879d 100644 --- a/protocol/socks/socks4/protocol.go +++ b/protocol/socks/socks4/protocol.go @@ -85,9 +85,7 @@ func WriteRequest(writer io.Writer, request Request) error { requestLen += len(request.Username) } - _buffer := buf.StackNewSize(requestLen) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(requestLen) defer buffer.Release() common.Must( @@ -145,9 +143,7 @@ func ReadResponse(reader io.Reader) (response Response, err error) { } func WriteResponse(writer io.Writer, response Response) error { - _buffer := buf.StackNewSize(8) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(8) defer buffer.Release() common.Must( buffer.WriteByte(0), diff --git a/protocol/socks/socks5/protocol.go b/protocol/socks/socks5/protocol.go index 79ab96f..bce361b 100644 --- a/protocol/socks/socks5/protocol.go +++ b/protocol/socks/socks5/protocol.go @@ -48,9 +48,7 @@ type AuthRequest struct { } func WriteAuthRequest(writer io.Writer, request AuthRequest) error { - _buffer := buf.StackNewSize(len(request.Methods) + 2) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(len(request.Methods) + 2) defer buffer.Release() common.Must( buffer.WriteByte(Version), @@ -120,9 +118,7 @@ type UsernamePasswordAuthRequest struct { } func WriteUsernamePasswordAuthRequest(writer io.Writer, request UsernamePasswordAuthRequest) error { - _buffer := buf.StackNewSize(3 + len(request.Username) + len(request.Password)) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(3 + len(request.Username) + len(request.Password)) defer buffer.Release() common.Must( buffer.WriteByte(1), @@ -191,9 +187,7 @@ type Request struct { } func WriteRequest(writer io.Writer, request Request) error { - _buffer := buf.StackNewSize(3 + M.SocksaddrSerializer.AddrPortLen(request.Destination)) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(3 + M.SocksaddrSerializer.AddrPortLen(request.Destination)) defer buffer.Release() common.Must( buffer.WriteByte(Version), @@ -244,9 +238,7 @@ func WriteResponse(writer io.Writer, response Response) error { bind.Addr = netip.IPv4Unspecified() } - _buffer := buf.StackNewSize(3 + M.SocksaddrSerializer.AddrPortLen(bind)) - defer common.KeepAlive(_buffer) - buffer := common.Dup(_buffer) + buffer := buf.NewSize(3 + M.SocksaddrSerializer.AddrPortLen(bind)) defer buffer.Release() common.Must( buffer.WriteByte(Version),