From cd8ec2833c21dda3c4152e2b83481fe9ce87d2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 14 Jun 2022 17:41:39 +0800 Subject: [PATCH] More padding --- go.mod | 4 ++-- go.sum | 8 +++---- shadowaead_2022/protocol.go | 37 ++++++++++++++++++++++++++------ shadowaead_2022/service.go | 20 +++++++++++++---- shadowaead_2022/service_multi.go | 6 +++--- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index b6018f1..55e4fd4 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module github.com/sagernet/sing-shadowsocks go 1.18 require ( - github.com/sagernet/sing v0.0.0-20220610074707-a30d5506be41 + github.com/sagernet/sing v0.0.0-20220614091938-64835a637bdc golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e lukechampine.com/blake3 v1.1.7 ) require ( github.com/klauspost/cpuid/v2 v2.0.12 // indirect - golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 // indirect + golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect ) diff --git a/go.sum b/go.sum index a48647d..0f3fc2c 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 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.0.0-20220610074707-a30d5506be41 h1:vquZangXPhZJJz5PMCn/6qOYk+c4dtk/fb7HpDlof2I= -github.com/sagernet/sing v0.0.0-20220610074707-a30d5506be41/go.mod h1:ZEo7wZBfJmzm8uwnbCtWEHw9GsIfSThSylZYcR+H/Zw= +github.com/sagernet/sing v0.0.0-20220614091938-64835a637bdc h1:AdNTzzSw6SCZI71GB+Am7cr+oUDUrBUaOi17FxDtNMw= +github.com/sagernet/sing v0.0.0-20220614091938-64835a637bdc/go.mod h1:Bgwxr10oTxYlQ33MgsXW3GuS2w5St11qqk4DqzJOdU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 h1:z8Hj/bl9cOV2grsOpEaQFUaly0JWN3i97mo3jXKJNp0= -golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= diff --git a/shadowaead_2022/protocol.go b/shadowaead_2022/protocol.go index c86ff4b..4cddbdb 100644 --- a/shadowaead_2022/protocol.go +++ b/shadowaead_2022/protocol.go @@ -267,7 +267,7 @@ func (c *clientConn) writeRequest(payload []byte) error { common.Must(fixedLengthBuffer.WriteByte(HeaderTypeClient)) common.Must(binary.Write(fixedLengthBuffer, binary.BigEndian, uint64(time.Now().Unix()))) var paddingLen int - if len(payload) == 0 { + if len(payload) < MaxPaddingLength { paddingLen = mRand.Intn(MaxPaddingLength) + 1 } variableLengthHeaderLen := M.SocksaddrSerializer.AddrPortLen(c.destination) + 2 + paddingLen + len(payload) @@ -281,7 +281,8 @@ func (c *clientConn) writeRequest(payload []byte) error { common.Must(binary.Write(variableLengthBuffer, binary.BigEndian, uint16(paddingLen))) if paddingLen > 0 { variableLengthBuffer.Extend(paddingLen) - } else { + } + if len(payload) > 0 { common.Must1(variableLengthBuffer.Write(payload)) } writer.WriteChunk(header, variableLengthBuffer.Slice()) @@ -438,6 +439,12 @@ func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksad if c.udpCipher != nil { hdrLen = PacketNonceSize } + + var paddingLen int + if destination.Port == 53 && buffer.Len() < MaxPaddingLength { + paddingLen = mRand.Intn(MaxPaddingLength-buffer.Len()) + 1 + } + hdrLen += 16 // packet header pskLen := len(c.pskList) if c.udpCipher == nil && pskLen > 1 { @@ -446,6 +453,7 @@ func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksad hdrLen += 1 // header type hdrLen += 8 // timestamp hdrLen += 2 // padding length + hdrLen += paddingLen hdrLen += M.SocksaddrSerializer.AddrPortLen(destination) header := buf.With(buffer.ExtendHeader(hdrLen)) @@ -488,8 +496,13 @@ func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksad common.Must( header.WriteByte(HeaderTypeClient), binary.Write(header, binary.BigEndian, uint64(time.Now().Unix())), - binary.Write(header, binary.BigEndian, uint16(0)), // padding length + binary.Write(header, binary.BigEndian, uint16(paddingLen)), // padding length ) + + if paddingLen > 0 { + header.Extend(paddingLen) + } + err := M.SocksaddrSerializer.WriteAddrPort(header, destination) if err != nil { return err @@ -613,12 +626,12 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { return M.Socksaddr{}, ErrBadClientSessionId } - var paddingLength uint16 - err = binary.Read(buffer, binary.BigEndian, &paddingLength) + var paddingLen uint16 + err = binary.Read(buffer, binary.BigEndian, &paddingLen) if err != nil { return M.Socksaddr{}, E.Cause(err, "read padding length") } - buffer.Advance(int(paddingLength)) + buffer.Advance(int(paddingLen)) destination, err := M.SocksaddrSerializer.ReadAddrPort(buffer) if err != nil { @@ -651,9 +664,14 @@ func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { if c.udpCipher == nil && pskLen > 1 { overHead += (pskLen - 1) * aes.BlockSize } + var paddingLen int + if destination.Port == 53 && len(p) < MaxPaddingLength { + paddingLen = mRand.Intn(MaxPaddingLength-len(p)) + 1 + } overHead += 1 // header type overHead += 8 // timestamp overHead += 2 // padding length + overHead += paddingLen overHead += M.SocksaddrSerializer.AddrPortLen(destination) _buffer := buf.StackNewSize(overHead + len(p)) @@ -700,8 +718,13 @@ func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { common.Must( buffer.WriteByte(HeaderTypeClient), binary.Write(buffer, binary.BigEndian, uint64(time.Now().Unix())), - binary.Write(buffer, binary.BigEndian, uint16(0)), // padding length + binary.Write(buffer, binary.BigEndian, uint16(paddingLen)), // padding length ) + + if paddingLen > 0 { + buffer.Extend(paddingLen) + } + err = M.SocksaddrSerializer.WriteAddrPort(buffer, destination) if err != nil { return diff --git a/shadowaead_2022/service.go b/shadowaead_2022/service.go index 2b378f4..616a542 100644 --- a/shadowaead_2022/service.go +++ b/shadowaead_2022/service.go @@ -9,6 +9,7 @@ import ( "encoding/binary" "io" "math" + mRand "math/rand" "net" "os" "sync" @@ -404,13 +405,13 @@ process: goto returnErr } - var paddingLength uint16 - err = binary.Read(buffer, binary.BigEndian, &paddingLength) + var paddingLen uint16 + err = binary.Read(buffer, binary.BigEndian, &paddingLen) if err != nil { err = E.Cause(err, "read padding length") goto returnErr } - buffer.Advance(int(paddingLength)) + buffer.Advance(int(paddingLen)) destination, err := M.SocksaddrSerializer.ReadAddrPort(buffer) if err != nil { @@ -439,11 +440,18 @@ func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socks if w.udpCipher != nil { hdrLen = PacketNonceSize } + + var paddingLen int + if destination.Port == 53 && buffer.Len() < MaxPaddingLength { + paddingLen = mRand.Intn(MaxPaddingLength-buffer.Len()) + 1 + } + hdrLen += 16 // packet header hdrLen += 1 // header type hdrLen += 8 // timestamp hdrLen += 8 // remote session id hdrLen += 2 // padding length + hdrLen += paddingLen hdrLen += M.SocksaddrSerializer.AddrPortLen(destination) header := buf.With(buffer.ExtendHeader(hdrLen)) @@ -461,9 +469,13 @@ func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socks header.WriteByte(HeaderTypeServer), binary.Write(header, binary.BigEndian, uint64(time.Now().Unix())), binary.Write(header, binary.BigEndian, w.session.remoteSessionId), - binary.Write(header, binary.BigEndian, uint16(0)), // padding length + binary.Write(header, binary.BigEndian, uint16(paddingLen)), // padding length ) + if paddingLen > 0 { + header.Extend(paddingLen) + } + err := M.SocksaddrSerializer.WriteAddrPort(header, destination) if err != nil { buffer.Release() diff --git a/shadowaead_2022/service_multi.go b/shadowaead_2022/service_multi.go index a88cf1f..ee5add6 100644 --- a/shadowaead_2022/service_multi.go +++ b/shadowaead_2022/service_multi.go @@ -335,13 +335,13 @@ process: goto returnErr } - var paddingLength uint16 - err = binary.Read(buffer, binary.BigEndian, &paddingLength) + var paddingLen uint16 + err = binary.Read(buffer, binary.BigEndian, &paddingLen) if err != nil { err = E.Cause(err, "read padding length") goto returnErr } - buffer.Advance(int(paddingLength)) + buffer.Advance(int(paddingLen)) destination, err := M.SocksaddrSerializer.ReadAddrPort(buffer) if err != nil {