mirror of
https://github.com/SagerNet/sing-shadowsocks.git
synced 2025-04-01 19:07:39 +03:00
Remove stack buffer usage
This commit is contained in:
parent
f3f7b6309b
commit
b044960bd3
11 changed files with 55 additions and 182 deletions
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module github.com/sagernet/sing-shadowsocks
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/sagernet/sing v0.2.5
|
||||
github.com/sagernet/sing v0.2.8-0.20230703002104-c68251b6d059
|
||||
golang.org/x/crypto v0.10.0
|
||||
lukechampine.com/blake3 v1.2.1
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,7 +1,7 @@
|
|||
github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE=
|
||||
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/sagernet/sing v0.2.5 h1:N8sUluR8GZvR9DqUiH3FA3vBb4m/EDdOVTYUrDzJvmY=
|
||||
github.com/sagernet/sing v0.2.5/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
github.com/sagernet/sing v0.2.8-0.20230703002104-c68251b6d059 h1:nqTONy58Gq1mdoGx9GX+GKXdSTwOPTKF/DXK+Wn4B+A=
|
||||
github.com/sagernet/sing v0.2.8-0.20230703002104-c68251b6d059/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
|
|
17
none.go
17
none.go
|
@ -2,13 +2,11 @@ package shadowsocks
|
|||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/udpnat"
|
||||
|
@ -96,17 +94,6 @@ func (c *noneConn) FrontHeadroom() int {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (c *noneConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
if !c.handshake {
|
||||
return bufio.ReadFrom0(c, r)
|
||||
}
|
||||
return bufio.Copy(c.Conn, r)
|
||||
}
|
||||
|
||||
func (c *noneConn) WriteTo(w io.Writer) (n int64, err error) {
|
||||
return bufio.Copy(w, c.Conn)
|
||||
}
|
||||
|
||||
func (c *noneConn) RemoteAddr() net.Addr {
|
||||
return c.destination.TCPAddr()
|
||||
}
|
||||
|
@ -166,9 +153,7 @@ func (c *nonePacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
|||
|
||||
func (c *nonePacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
destination := M.SocksaddrFromNet(addr)
|
||||
_buffer := buf.StackNewSize(M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
buffer := buf.NewSize(M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
|
||||
defer buffer.Release()
|
||||
err = M.SocksaddrSerializer.WriteAddrPort(buffer, destination)
|
||||
if err != nil {
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/sagernet/sing-shadowsocks"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
|
@ -118,19 +117,15 @@ type clientConn struct {
|
|||
}
|
||||
|
||||
func (c *clientConn) writeRequest(payload []byte) error {
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
defer common.KeepAlive(_salt)
|
||||
salt := common.Dup(_salt)
|
||||
salt := buf.NewSize(c.keySaltLength)
|
||||
defer salt.Release()
|
||||
salt.WriteRandom(c.keySaltLength)
|
||||
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(c.keySaltLength)
|
||||
|
||||
Kdf(c.key, salt.Bytes(), key)
|
||||
writeCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -166,17 +161,13 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
}
|
||||
|
||||
func (c *clientConn) readResponse() error {
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
defer common.KeepAlive(_salt)
|
||||
salt := common.Dup(_salt)
|
||||
salt := buf.NewSize(c.keySaltLength)
|
||||
defer salt.Release()
|
||||
_, err := salt.ReadFullFrom(c.Conn, c.keySaltLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
defer common.KeepAlive(_key)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(c.keySaltLength)
|
||||
defer key.Release()
|
||||
Kdf(c.key, salt.Bytes(), key)
|
||||
readCipher, err := c.constructor(key.Bytes())
|
||||
|
@ -220,13 +211,6 @@ func (c *clientConn) Write(p []byte) (n int, err error) {
|
|||
return c.writer.Write(p)
|
||||
}
|
||||
|
||||
func (c *clientConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
if c.writer == nil {
|
||||
return bufio.ReadFrom0(c, r)
|
||||
}
|
||||
return c.writer.ReadFrom(r)
|
||||
}
|
||||
|
||||
func (c *clientConn) NeedHandshake() bool {
|
||||
return c.writer == nil
|
||||
}
|
||||
|
@ -249,12 +233,10 @@ func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksad
|
|||
header := buf.With(buffer.ExtendHeader(c.keySaltLength + M.SocksaddrSerializer.AddrPortLen(destination)))
|
||||
header.WriteRandom(c.keySaltLength)
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(c.keySaltLength)
|
||||
Kdf(c.key, buffer.To(c.keySaltLength), key)
|
||||
writeCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -272,12 +254,10 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
|||
if buffer.Len() < c.keySaltLength {
|
||||
return M.Socksaddr{}, io.ErrShortBuffer
|
||||
}
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(c.keySaltLength)
|
||||
Kdf(c.key, buffer.To(c.keySaltLength), key)
|
||||
readCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
|
@ -310,9 +290,8 @@ func (c *clientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
|||
|
||||
func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
destination := M.SocksaddrFromNet(addr)
|
||||
_buffer := buf.StackNewSize(c.keySaltLength + M.SocksaddrSerializer.AddrPortLen(destination) + len(p) + Overhead)
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
buffer := buf.NewSize(c.keySaltLength + M.SocksaddrSerializer.AddrPortLen(destination) + len(p) + Overhead)
|
||||
defer buffer.Release()
|
||||
buffer.Resize(c.keySaltLength+M.SocksaddrSerializer.AddrPortLen(destination), 0)
|
||||
common.Must1(buffer.Write(p))
|
||||
err = c.WritePacket(buffer, destination)
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/sagernet/sing-shadowsocks"
|
||||
"github.com/sagernet/sing/common"
|
||||
"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"
|
||||
|
@ -60,9 +59,7 @@ func (s *Service) NewConnection(ctx context.Context, conn net.Conn, metadata M.M
|
|||
}
|
||||
|
||||
func (s *Service) newConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
_header := buf.StackNewSize(s.keySaltLength + PacketLengthBufferSize + Overhead)
|
||||
defer common.KeepAlive(_header)
|
||||
header := common.Dup(_header)
|
||||
header := buf.NewSize(s.keySaltLength + PacketLengthBufferSize + Overhead)
|
||||
defer header.Release()
|
||||
|
||||
_, err := header.ReadFullFrom(conn, header.FreeLen())
|
||||
|
@ -72,12 +69,10 @@ func (s *Service) newConnection(ctx context.Context, conn net.Conn, metadata M.M
|
|||
return ErrBadHeader
|
||||
}
|
||||
|
||||
_key := buf.StackNewSize(s.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(s.keySaltLength)
|
||||
Kdf(s.key, header.To(s.keySaltLength), key)
|
||||
readCipher, err := s.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -116,20 +111,16 @@ type serverConn struct {
|
|||
}
|
||||
|
||||
func (c *serverConn) writeResponse(payload []byte) (n int, err error) {
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
salt := common.Dup(_salt)
|
||||
salt := buf.NewSize(c.keySaltLength)
|
||||
salt.WriteRandom(c.keySaltLength)
|
||||
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(c.keySaltLength)
|
||||
|
||||
Kdf(c.key, salt.Bytes(), key)
|
||||
writeCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
return
|
||||
}
|
||||
writer := NewWriter(c.Conn, writeCipher, MaxPacketSize)
|
||||
|
@ -137,7 +128,6 @@ func (c *serverConn) writeResponse(payload []byte) (n int, err error) {
|
|||
header := writer.Buffer()
|
||||
common.Must1(header.Write(salt.Bytes()))
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
|
||||
bufferedWriter := writer.BufferedWriter(header.Len())
|
||||
if len(payload) > 0 {
|
||||
|
@ -173,13 +163,6 @@ func (c *serverConn) Write(p []byte) (n int, err error) {
|
|||
return c.writeResponse(p)
|
||||
}
|
||||
|
||||
func (c *serverConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
if c.writer == nil {
|
||||
return bufio.ReadFrom0(c, r)
|
||||
}
|
||||
return c.writer.ReadFrom(r)
|
||||
}
|
||||
|
||||
func (c *serverConn) WriteTo(w io.Writer) (n int64, err error) {
|
||||
return c.reader.WriteTo(w)
|
||||
}
|
||||
|
@ -211,12 +194,10 @@ func (s *Service) newPacket(ctx context.Context, conn N.PacketConn, buffer *buf.
|
|||
if buffer.Len() < s.keySaltLength {
|
||||
return io.ErrShortBuffer
|
||||
}
|
||||
_key := buf.StackNewSize(s.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(s.keySaltLength)
|
||||
Kdf(s.key, buffer.To(s.keySaltLength), key)
|
||||
readCipher, err := s.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -254,12 +235,10 @@ func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socks
|
|||
buffer.Release()
|
||||
return err
|
||||
}
|
||||
_key := buf.StackNewSize(w.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(w.keySaltLength)
|
||||
Kdf(w.key, buffer.To(w.keySaltLength), key)
|
||||
writeCipher, err := w.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing-shadowsocks"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio/deadline"
|
||||
|
@ -85,9 +84,7 @@ func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, meta
|
|||
if method == nil {
|
||||
return shadowsocks.ErrNoUsers
|
||||
}
|
||||
_header := buf.StackNewSize(method.keySaltLength + PacketLengthBufferSize + Overhead)
|
||||
defer common.KeepAlive(_header)
|
||||
header := common.Dup(_header)
|
||||
header := buf.NewSize(method.keySaltLength + PacketLengthBufferSize + Overhead)
|
||||
defer header.Release()
|
||||
|
||||
_, err := header.ReadFullFrom(conn, header.FreeLen())
|
||||
|
@ -100,12 +97,10 @@ func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, meta
|
|||
var reader *Reader
|
||||
var readCipher cipher.AEAD
|
||||
for u, m := range s.methodMap {
|
||||
_key := buf.StackNewSize(method.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(method.keySaltLength)
|
||||
Kdf(m.key, header.To(m.keySaltLength), key)
|
||||
readCipher, err = m.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -165,12 +160,10 @@ func (s *MultiService[U]) newPacket(ctx context.Context, conn N.PacketConn, buff
|
|||
var readCipher cipher.AEAD
|
||||
var err error
|
||||
for u, m := range s.methodMap {
|
||||
_key := buf.StackNewSize(m.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
key := buf.NewSize(m.keySaltLength)
|
||||
Kdf(m.key, buffer.To(m.keySaltLength), key)
|
||||
readCipher, err = m.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -156,10 +156,10 @@ func Key(key []byte, keyLength int) []byte {
|
|||
}
|
||||
|
||||
func SessionKey(psk []byte, salt []byte, keyLength int) []byte {
|
||||
sessionKey := buf.Make(len(psk) + len(salt))
|
||||
sessionKey := make([]byte, len(psk)+len(salt))
|
||||
copy(sessionKey, psk)
|
||||
copy(sessionKey[len(psk):], salt)
|
||||
outKey := buf.Make(keyLength)
|
||||
outKey := make([]byte, keyLength)
|
||||
blake3.DeriveKey(outKey, "shadowsocks 2022 session subkey", sessionKey)
|
||||
return outKey
|
||||
}
|
||||
|
@ -236,11 +236,10 @@ func (m *Method) writeExtendedIdentityHeaders(request *buf.Buffer, salt []byte)
|
|||
return nil
|
||||
}
|
||||
for i, psk := range m.pskList {
|
||||
keyMaterial := buf.Make(m.keySaltLength * 2)
|
||||
keyMaterial := make([]byte, m.keySaltLength*2)
|
||||
copy(keyMaterial, psk)
|
||||
copy(keyMaterial[m.keySaltLength:], salt)
|
||||
_identitySubkey := buf.StackNewSize(m.keySaltLength)
|
||||
identitySubkey := common.Dup(_identitySubkey)
|
||||
identitySubkey := buf.NewSize(m.keySaltLength)
|
||||
identitySubkey.Extend(identitySubkey.FreeLen())
|
||||
blake3.DeriveKey(identitySubkey.Bytes(), "shadowsocks 2022 identity subkey", keyMaterial)
|
||||
|
||||
|
@ -253,7 +252,6 @@ func (m *Method) writeExtendedIdentityHeaders(request *buf.Buffer, salt []byte)
|
|||
}
|
||||
b.Encrypt(header, pskHash)
|
||||
identitySubkey.Release()
|
||||
common.KeepAlive(_identitySubkey)
|
||||
if i == pskLen-2 {
|
||||
break
|
||||
}
|
||||
|
@ -266,7 +264,7 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
common.Must1(io.ReadFull(rand.Reader, salt))
|
||||
|
||||
key := SessionKey(c.pskList[len(c.pskList)-1], salt, c.keySaltLength)
|
||||
writeCipher, err := c.constructor(common.Dup(key))
|
||||
writeCipher, err := c.constructor(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -275,7 +273,6 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
writeCipher,
|
||||
MaxPacketSize,
|
||||
)
|
||||
common.KeepAlive(key)
|
||||
|
||||
header := writer.Buffer()
|
||||
header.Write(salt)
|
||||
|
@ -286,7 +283,7 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
}
|
||||
|
||||
var _fixedLengthBuffer [RequestHeaderFixedChunkLength]byte
|
||||
fixedLengthBuffer := buf.With(common.Dup(_fixedLengthBuffer[:]))
|
||||
fixedLengthBuffer := buf.With(_fixedLengthBuffer[:])
|
||||
common.Must(fixedLengthBuffer.WriteByte(HeaderTypeClient))
|
||||
common.Must(binary.Write(fixedLengthBuffer, binary.BigEndian, uint64(c.time().Unix())))
|
||||
var paddingLen int
|
||||
|
@ -298,10 +295,8 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
variableLengthHeaderLen += payloadLen
|
||||
common.Must(binary.Write(fixedLengthBuffer, binary.BigEndian, uint16(variableLengthHeaderLen)))
|
||||
writer.WriteChunk(header, fixedLengthBuffer.Slice())
|
||||
common.KeepAlive(_fixedLengthBuffer)
|
||||
|
||||
_variableLengthBuffer := buf.StackNewSize(variableLengthHeaderLen)
|
||||
variableLengthBuffer := common.Dup(_variableLengthBuffer)
|
||||
variableLengthBuffer := buf.NewSize(variableLengthHeaderLen)
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(variableLengthBuffer, c.destination))
|
||||
common.Must(binary.Write(variableLengthBuffer, binary.BigEndian, uint16(paddingLen)))
|
||||
if paddingLen > 0 {
|
||||
|
@ -311,7 +306,6 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
common.Must1(variableLengthBuffer.Write(payload[:payloadLen]))
|
||||
}
|
||||
writer.WriteChunk(header, variableLengthBuffer.Slice())
|
||||
common.KeepAlive(_variableLengthBuffer)
|
||||
variableLengthBuffer.Release()
|
||||
|
||||
err = writer.BufferedWriter(header.Len()).Flush()
|
||||
|
@ -329,22 +323,18 @@ func (c *clientConn) readResponse() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
salt := common.Dup(_salt)
|
||||
salt := buf.NewSize(c.keySaltLength)
|
||||
|
||||
_, err := salt.ReadFullFrom(c.Conn, salt.FreeLen())
|
||||
if err != nil {
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
key := SessionKey(c.pskList[len(c.pskList)-1], salt.Bytes(), c.keySaltLength)
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
|
||||
readCipher, err := c.constructor(common.Dup(key))
|
||||
readCipher, err := c.constructor(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -353,7 +343,6 @@ func (c *clientConn) readResponse() error {
|
|||
readCipher,
|
||||
MaxPacketSize,
|
||||
)
|
||||
common.KeepAlive(key)
|
||||
|
||||
err = reader.ReadWithLength(uint16(1 + 8 + c.keySaltLength + 2))
|
||||
if err != nil {
|
||||
|
@ -379,8 +368,7 @@ func (c *clientConn) readResponse() error {
|
|||
return E.Extend(ErrBadTimestamp, "received ", epoch, ", diff ", diff, "s")
|
||||
}
|
||||
|
||||
_requestSalt := buf.StackNewSize(c.keySaltLength)
|
||||
requestSalt := common.Dup(_requestSalt)
|
||||
requestSalt := buf.NewSize(c.keySaltLength)
|
||||
_, err = requestSalt.ReadFullFrom(reader, requestSalt.FreeLen())
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -390,7 +378,6 @@ func (c *clientConn) readResponse() error {
|
|||
return ErrBadRequestSalt
|
||||
}
|
||||
requestSalt.Release()
|
||||
common.KeepAlive(_requestSalt)
|
||||
c.requestSalt = nil
|
||||
|
||||
var length uint16
|
||||
|
@ -449,13 +436,6 @@ func (c *clientConn) WriteVectorised(buffers []*buf.Buffer) error {
|
|||
return c.writer.WriteVectorised(buffers[1:])
|
||||
}
|
||||
|
||||
func (c *clientConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
if c.writer == nil {
|
||||
return bufio.ReadFrom0(c, r)
|
||||
}
|
||||
return bufio.Copy(c.writer, r)
|
||||
}
|
||||
|
||||
func (c *clientConn) NeedHandshake() bool {
|
||||
return c.writer == nil
|
||||
}
|
||||
|
@ -620,11 +600,10 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
|||
remoteCipher = c.session.lastRemoteCipher
|
||||
} else {
|
||||
key := SessionKey(c.pskList[len(c.pskList)-1], packetHeader[:8], c.keySaltLength)
|
||||
remoteCipher, err = c.constructor(common.Dup(key))
|
||||
remoteCipher, err = c.constructor(key)
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
common.KeepAlive(key)
|
||||
}
|
||||
_, err = remoteCipher.Open(buffer.Index(0), packetHeader[4:16], buffer.Bytes(), nil)
|
||||
if err != nil {
|
||||
|
@ -737,9 +716,7 @@ func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
|||
overHead += paddingLen
|
||||
overHead += M.SocksaddrSerializer.AddrPortLen(destination)
|
||||
|
||||
_buffer := buf.StackNewSize(overHead + len(p))
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
buffer := buf.NewSize(overHead + len(p))
|
||||
defer buffer.Release()
|
||||
|
||||
var dataIndex int
|
||||
|
@ -863,11 +840,10 @@ func (m *Method) newUDPSession() *udpSession {
|
|||
binary.BigEndian.PutUint64(sessionId, session.sessionId)
|
||||
key := SessionKey(m.pskList[len(m.pskList)-1], sessionId, m.keySaltLength)
|
||||
var err error
|
||||
session.cipher, err = m.constructor(common.Dup(key))
|
||||
session.cipher, err = m.constructor(key)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
common.KeepAlive(key)
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
|
||||
"github.com/sagernet/sing-shadowsocks"
|
||||
"github.com/sagernet/sing-shadowsocks/shadowaead"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
|
@ -153,9 +152,7 @@ func (s *RelayService[U]) NewConnection(ctx context.Context, conn net.Conn, meta
|
|||
}
|
||||
|
||||
func (s *RelayService[U]) newConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
_requestHeader := buf.StackNew()
|
||||
defer common.KeepAlive(_requestHeader)
|
||||
requestHeader := common.Dup(_requestHeader)
|
||||
requestHeader := buf.New()
|
||||
defer requestHeader.Release()
|
||||
n, err := requestHeader.ReadOnceFrom(conn)
|
||||
if err != nil {
|
||||
|
@ -165,19 +162,17 @@ func (s *RelayService[U]) newConnection(ctx context.Context, conn net.Conn, meta
|
|||
}
|
||||
requestSalt := requestHeader.To(s.keySaltLength)
|
||||
var _eiHeader [aes.BlockSize]byte
|
||||
eiHeader := common.Dup(_eiHeader[:])
|
||||
eiHeader := _eiHeader[:]
|
||||
copy(eiHeader, requestHeader.Range(s.keySaltLength, s.keySaltLength+aes.BlockSize))
|
||||
|
||||
keyMaterial := buf.Make(s.keySaltLength * 2)
|
||||
keyMaterial := make([]byte, s.keySaltLength*2)
|
||||
copy(keyMaterial, s.iPSK)
|
||||
copy(keyMaterial[s.keySaltLength:], requestSalt)
|
||||
_identitySubkey := buf.StackNewSize(s.keySaltLength)
|
||||
identitySubkey := common.Dup(_identitySubkey)
|
||||
identitySubkey := buf.NewSize(s.keySaltLength)
|
||||
identitySubkey.Extend(identitySubkey.FreeLen())
|
||||
blake3.DeriveKey(identitySubkey.Bytes(), "shadowsocks 2022 identity subkey", keyMaterial)
|
||||
b, err := s.blockConstructor(identitySubkey.Bytes())
|
||||
identitySubkey.Release()
|
||||
common.KeepAlive(_identitySubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -189,7 +184,6 @@ func (s *RelayService[U]) newConnection(ctx context.Context, conn net.Conn, meta
|
|||
} else {
|
||||
return E.New("invalid request")
|
||||
}
|
||||
common.KeepAlive(_eiHeader)
|
||||
|
||||
copy(requestHeader.Range(aes.BlockSize, aes.BlockSize+s.keySaltLength), requestHeader.To(s.keySaltLength))
|
||||
requestHeader.Advance(aes.BlockSize)
|
||||
|
@ -218,7 +212,7 @@ func (s *RelayService[U]) newPacket(ctx context.Context, conn N.PacketConn, buff
|
|||
sessionId := binary.BigEndian.Uint64(packetHeader)
|
||||
|
||||
var _eiHeader [aes.BlockSize]byte
|
||||
eiHeader := common.Dup(_eiHeader[:])
|
||||
eiHeader := _eiHeader[:]
|
||||
s.udpBlockCipher.Decrypt(eiHeader, buffer.Range(aes.BlockSize, 2*aes.BlockSize))
|
||||
xorWords(eiHeader, eiHeader, packetHeader)
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"github.com/sagernet/sing-shadowsocks/shadowaead"
|
||||
"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"
|
||||
|
@ -162,7 +161,7 @@ func (s *Service) newConnection(ctx context.Context, conn net.Conn, metadata M.M
|
|||
}
|
||||
|
||||
requestKey := SessionKey(s.psk, requestSalt, s.keySaltLength)
|
||||
readCipher, err := s.constructor(common.Dup(requestKey))
|
||||
readCipher, err := s.constructor(requestKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -171,7 +170,6 @@ func (s *Service) newConnection(ctx context.Context, conn net.Conn, metadata M.M
|
|||
readCipher,
|
||||
MaxPacketSize,
|
||||
)
|
||||
common.KeepAlive(requestKey)
|
||||
|
||||
err = reader.ReadExternalChunk(header[s.keySaltLength:])
|
||||
if err != nil {
|
||||
|
@ -260,16 +258,13 @@ type serverConn struct {
|
|||
}
|
||||
|
||||
func (c *serverConn) writeResponse(payload []byte) (n int, err error) {
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
salt := common.Dup(_salt)
|
||||
salt := buf.NewSize(c.keySaltLength)
|
||||
salt.WriteRandom(salt.FreeLen())
|
||||
|
||||
key := SessionKey(c.uPSK, salt.Bytes(), c.keySaltLength)
|
||||
common.KeepAlive(_salt)
|
||||
writeCipher, err := c.constructor(common.Dup(key))
|
||||
writeCipher, err := c.constructor(key)
|
||||
if err != nil {
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
return
|
||||
}
|
||||
writer := shadowaead.NewWriter(
|
||||
|
@ -277,18 +272,15 @@ func (c *serverConn) writeResponse(payload []byte) (n int, err error) {
|
|||
writeCipher,
|
||||
MaxPacketSize,
|
||||
)
|
||||
common.KeepAlive(key)
|
||||
header := writer.Buffer()
|
||||
header.Write(salt.Bytes())
|
||||
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
|
||||
headerType := byte(HeaderTypeServer)
|
||||
payloadLen := len(payload)
|
||||
|
||||
_headerFixedChunk := buf.StackNewSize(1 + 8 + c.keySaltLength + 2)
|
||||
headerFixedChunk := common.Dup(_headerFixedChunk)
|
||||
headerFixedChunk := buf.NewSize(1 + 8 + c.keySaltLength + 2)
|
||||
common.Must(headerFixedChunk.WriteByte(headerType))
|
||||
common.Must(binary.Write(headerFixedChunk, binary.BigEndian, uint64(c.time().Unix())))
|
||||
common.Must1(headerFixedChunk.Write(c.requestSalt))
|
||||
|
@ -296,7 +288,6 @@ func (c *serverConn) writeResponse(payload []byte) (n int, err error) {
|
|||
|
||||
writer.WriteChunk(header, headerFixedChunk.Slice())
|
||||
headerFixedChunk.Release()
|
||||
common.KeepAlive(_headerFixedChunk)
|
||||
c.requestSalt = nil
|
||||
|
||||
if payloadLen > 0 {
|
||||
|
@ -362,17 +353,6 @@ func (c *serverConn) WriteVectorised(buffers []*buf.Buffer) error {
|
|||
return c.writer.WriteVectorised(buffers[1:])
|
||||
}
|
||||
|
||||
func (c *serverConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
if c.writer == nil {
|
||||
return bufio.ReadFrom0(c, r)
|
||||
}
|
||||
return bufio.Copy(c.writer, r)
|
||||
}
|
||||
|
||||
func (c *serverConn) WriteTo(w io.Writer) (n int64, err error) {
|
||||
return bufio.Copy(w, c.reader)
|
||||
}
|
||||
|
||||
func (c *serverConn) Close() error {
|
||||
return common.Close(
|
||||
c.Conn,
|
||||
|
@ -435,11 +415,10 @@ func (s *Service) newPacket(ctx context.Context, conn N.PacketConn, buffer *buf.
|
|||
session.remoteSessionId = sessionId
|
||||
if packetHeader != nil {
|
||||
key := SessionKey(s.psk, packetHeader[:8], s.keySaltLength)
|
||||
session.remoteCipher, err = s.constructor(common.Dup(key))
|
||||
session.remoteCipher, err = s.constructor(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.KeepAlive(key)
|
||||
}
|
||||
}
|
||||
goto process
|
||||
|
@ -631,9 +610,8 @@ func (s *Service) newUDPSession() *serverUDPSession {
|
|||
binary.BigEndian.PutUint64(sessionId, session.sessionId)
|
||||
key := SessionKey(s.psk, sessionId, s.keySaltLength)
|
||||
var err error
|
||||
session.cipher, err = s.constructor(common.Dup(key))
|
||||
session.cipher, err = s.constructor(key)
|
||||
common.Must(err)
|
||||
common.KeepAlive(key)
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
|
|
@ -136,19 +136,17 @@ func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, meta
|
|||
}
|
||||
|
||||
var _eiHeader [aes.BlockSize]byte
|
||||
eiHeader := common.Dup(_eiHeader[:])
|
||||
eiHeader := _eiHeader[:]
|
||||
copy(eiHeader, requestHeader[s.keySaltLength:s.keySaltLength+aes.BlockSize])
|
||||
|
||||
keyMaterial := buf.Make(s.keySaltLength * 2)
|
||||
keyMaterial := make([]byte, s.keySaltLength*2)
|
||||
copy(keyMaterial, s.psk)
|
||||
copy(keyMaterial[s.keySaltLength:], requestSalt)
|
||||
_identitySubkey := buf.StackNewSize(s.keySaltLength)
|
||||
identitySubkey := common.Dup(_identitySubkey)
|
||||
identitySubkey := buf.NewSize(s.keySaltLength)
|
||||
identitySubkey.Extend(identitySubkey.FreeLen())
|
||||
blake3.DeriveKey(identitySubkey.Bytes(), "shadowsocks 2022 identity subkey", keyMaterial)
|
||||
b, err := s.blockConstructor(identitySubkey.Bytes())
|
||||
identitySubkey.Release()
|
||||
common.KeepAlive(_identitySubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -162,10 +160,9 @@ func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, meta
|
|||
} else {
|
||||
return E.New("invalid request")
|
||||
}
|
||||
common.KeepAlive(_eiHeader)
|
||||
|
||||
requestKey := SessionKey(uPSK, requestSalt, s.keySaltLength)
|
||||
readCipher, err := s.constructor(common.Dup(requestKey))
|
||||
readCipher, err := s.constructor(requestKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -265,7 +262,7 @@ func (s *MultiService[U]) newPacket(ctx context.Context, conn N.PacketConn, buff
|
|||
s.udpBlockCipher.Decrypt(packetHeader, packetHeader)
|
||||
|
||||
var _eiHeader [aes.BlockSize]byte
|
||||
eiHeader := common.Dup(_eiHeader[:])
|
||||
eiHeader := _eiHeader[:]
|
||||
s.udpBlockCipher.Decrypt(eiHeader, buffer.Range(aes.BlockSize, 2*aes.BlockSize))
|
||||
xorWords(eiHeader, eiHeader, packetHeader)
|
||||
|
||||
|
@ -296,11 +293,10 @@ func (s *MultiService[U]) newPacket(ctx context.Context, conn N.PacketConn, buff
|
|||
if !loaded {
|
||||
session.remoteSessionId = sessionId
|
||||
key := SessionKey(uPSK, packetHeader[:8], s.keySaltLength)
|
||||
session.remoteCipher, err = s.constructor(common.Dup(key))
|
||||
session.remoteCipher, err = s.constructor(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.KeepAlive(key)
|
||||
}
|
||||
|
||||
goto process
|
||||
|
@ -384,8 +380,7 @@ func (s *MultiService[U]) newUDPSession(uPSK []byte) *serverUDPSession {
|
|||
binary.BigEndian.PutUint64(sessionId, session.sessionId)
|
||||
key := SessionKey(uPSK, sessionId, s.keySaltLength)
|
||||
var err error
|
||||
session.cipher, err = s.constructor(common.Dup(key))
|
||||
session.cipher, err = s.constructor(key)
|
||||
common.Must(err)
|
||||
common.KeepAlive(key)
|
||||
return session
|
||||
}
|
||||
|
|
|
@ -167,9 +167,7 @@ type clientConn struct {
|
|||
}
|
||||
|
||||
func (c *clientConn) writeRequest() error {
|
||||
_buffer := buf.StackNewSize(c.saltLength + M.SocksaddrSerializer.AddrPortLen(c.destination))
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
buffer := buf.NewSize(c.saltLength + M.SocksaddrSerializer.AddrPortLen(c.destination))
|
||||
defer buffer.Release()
|
||||
|
||||
salt := buffer.Extend(c.saltLength)
|
||||
|
@ -200,9 +198,7 @@ func (c *clientConn) readResponse() error {
|
|||
if c.readStream != nil {
|
||||
return nil
|
||||
}
|
||||
_salt := buf.Make(c.saltLength)
|
||||
defer common.KeepAlive(_salt)
|
||||
salt := common.Dup(_salt)
|
||||
salt := make([]byte, c.saltLength)
|
||||
_, err := io.ReadFull(c.Conn, salt)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -308,9 +304,7 @@ func (c *clientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)
|
|||
|
||||
func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
destination := M.SocksaddrFromNet(addr)
|
||||
_buffer := buf.StackNewSize(c.saltLength + M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
buffer := buf.NewSize(c.saltLength + M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
|
||||
defer buffer.Release()
|
||||
common.Must1(buffer.ReadFullFrom(rand.Reader, c.saltLength))
|
||||
err = M.SocksaddrSerializer.WriteAddrPort(buffer, M.SocksaddrFromNet(addr))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue