diff --git a/protocol/shadowsocks/shadowaead/service.go b/protocol/shadowsocks/shadowaead/service.go index 0a508e2..ab80bb7 100644 --- a/protocol/shadowsocks/shadowaead/service.go +++ b/protocol/shadowsocks/shadowaead/service.go @@ -225,7 +225,14 @@ func (s *Service) newPacket(conn N.PacketConn, buffer *buf.Buffer, metadata M.Me } buffer.Advance(s.keySaltLength) buffer.Truncate(len(packet)) + + destination, err := socks5.AddressSerializer.ReadAddrPort(buffer) + if err != nil { + return err + } + metadata.Protocol = "shadowsocks" + metadata.Destination = destination s.udpNat.NewPacket(metadata.Source.AddrPort(), func() N.PacketWriter { return &serverPacketWriter{s, conn, metadata.Source} }, buffer, metadata) diff --git a/protocol/shadowsocks/shadowaead_2022/protocol.go b/protocol/shadowsocks/shadowaead_2022/protocol.go index 3df0059..9b67374 100644 --- a/protocol/shadowsocks/shadowaead_2022/protocol.go +++ b/protocol/shadowsocks/shadowaead_2022/protocol.go @@ -431,7 +431,7 @@ func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksad } hdrLen += 1 // header type hdrLen += 8 // timestamp - hdrLen += 1 // padding length + hdrLen += 2 // padding length hdrLen += socks5.AddressSerializer.AddrPortLen(destination) header := buf.With(buffer.ExtendHeader(hdrLen)) @@ -505,6 +505,7 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { return M.Socksaddr{}, E.Cause(err, "decrypt packet") } buffer.Advance(PacketNonceSize) + buffer.Truncate(buffer.Len() - c.method.udpCipher.Overhead()) } else { packetHeader = buffer.To(aes.BlockSize) c.method.udpBlockCipher.Decrypt(packetHeader, packetHeader) @@ -535,6 +536,7 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) { if err != nil { return M.Socksaddr{}, E.Cause(err, "decrypt packet") } + buffer.Truncate(buffer.Len() - remoteCipher.Overhead()) } var headerType byte diff --git a/protocol/shadowsocks/shadowaead_2022/service.go b/protocol/shadowsocks/shadowaead_2022/service.go index 74f2432..667a987 100644 --- a/protocol/shadowsocks/shadowaead_2022/service.go +++ b/protocol/shadowsocks/shadowaead_2022/service.go @@ -262,6 +262,7 @@ func (s *Service) newPacket(conn N.PacketConn, buffer *buf.Buffer, metadata M.Me return E.Cause(err, "decrypt packet header") } buffer.Advance(PacketNonceSize) + buffer.Truncate(buffer.Len() - s.udpCipher.Overhead()) } else { packetHeader = buffer.To(aes.BlockSize) s.udpBlockCipher.Decrypt(packetHeader, packetHeader) @@ -306,6 +307,7 @@ process: err = E.Cause(err, "decrypt packet") goto returnErr } + buffer.Truncate(buffer.Len() - session.remoteCipher.Overhead()) } var headerType byte @@ -324,7 +326,8 @@ process: if err != nil { goto returnErr } - if math.Abs(float64(uint64(time.Now().Unix())-epoch)) > 30 { + diff := int(math.Abs(float64(time.Now().Unix() - int64(epoch)))) + if diff > 30 { err = ErrBadTimestamp goto returnErr } @@ -357,11 +360,17 @@ type serverPacketWriter struct { } func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error { - defer buffer.Release() - - _header := buf.StackNew() - defer runtime.KeepAlive(_header) - header := common.Dup(_header) + var hdrLen int + if w.udpCipher != nil { + hdrLen = PacketNonceSize + } + hdrLen += 16 // packet header + hdrLen += 1 // header type + hdrLen += 8 // timestamp + hdrLen += 8 // remote session id + hdrLen += 2 // padding length + hdrLen += socks5.AddressSerializer.AddrPortLen(destination) + header := buf.With(buffer.ExtendHeader(hdrLen)) var dataIndex int if w.udpCipher != nil { @@ -385,21 +394,16 @@ func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socks return err } - _, err = header.Write(buffer.Bytes()) - if err != nil { - return err - } - if w.udpCipher != nil { - w.udpCipher.Seal(header.Index(dataIndex), header.To(dataIndex), header.From(dataIndex), nil) - header.Extend(w.udpCipher.Overhead()) + w.udpCipher.Seal(buffer.Index(dataIndex), buffer.To(dataIndex), buffer.From(dataIndex), nil) + buffer.Extend(w.udpCipher.Overhead()) } else { - packetHeader := header.To(aes.BlockSize) - w.session.cipher.Seal(header.Index(dataIndex), packetHeader[4:16], header.From(dataIndex), nil) - header.Extend(w.session.cipher.Overhead()) + packetHeader := buffer.To(aes.BlockSize) + w.session.cipher.Seal(buffer.Index(dataIndex), packetHeader[4:16], buffer.From(dataIndex), nil) + buffer.Extend(w.session.cipher.Overhead()) w.udpBlockCipher.Encrypt(packetHeader, packetHeader) } - return w.PacketConn.WritePacket(header, w.session.remoteAddr) + return w.PacketConn.WritePacket(buffer, w.session.remoteAddr) } type serverUDPSession struct { diff --git a/protocol/shadowsocks/shadowaead_2022/service_multi.go b/protocol/shadowsocks/shadowaead_2022/service_multi.go index 61626b2..81412ce 100644 --- a/protocol/shadowsocks/shadowaead_2022/service_multi.go +++ b/protocol/shadowsocks/shadowaead_2022/service_multi.go @@ -140,7 +140,8 @@ func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, meta if err != nil { return E.Cause(err, "read timestamp") } - if math.Abs(float64(time.Now().Unix()-int64(epoch))) > 30 { + diff := int(math.Abs(float64(time.Now().Unix() - int64(epoch)))) + if diff > 30 { return ErrBadTimestamp } @@ -246,6 +247,7 @@ process: err = E.Cause(err, "decrypt packet") goto returnErr } + buffer.Truncate(buffer.Len() - session.remoteCipher.Overhead()) } var headerType byte