diff --git a/proxy/vmess/protocol/vmess.go b/proxy/vmess/protocol/vmess.go index dd2d19a88..e1964f4da 100644 --- a/proxy/vmess/protocol/vmess.go +++ b/proxy/vmess/protocol/vmess.go @@ -161,48 +161,44 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) { } // ToBytes returns a VMessRequest in the form of byte array. -func (request *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user.RandomInt64InRange, buffer []byte) ([]byte, error) { +func (request *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user.RandomInt64InRange, buffer *alloc.Buffer) (*alloc.Buffer, error) { if buffer == nil { - buffer = make([]byte, 0, 300) + buffer = alloc.NewSmallBuffer().Clear() } counter := randomRangeInt64(time.Now().UTC().Unix(), 30) hash := idHash.Hash(request.UserId.Bytes[:], counter) - buffer = append(buffer, hash...) + buffer.Append(hash) - encryptionBegin := len(buffer) + encryptionBegin := buffer.Len() - buffer = append(buffer, request.Version) - buffer = append(buffer, request.RequestIV...) - buffer = append(buffer, request.RequestKey...) - buffer = append(buffer, request.ResponseHeader...) - buffer = append(buffer, request.Command) - buffer = append(buffer, request.Address.PortBytes()...) + buffer.AppendBytes(request.Version) + buffer.Append(request.RequestIV) + buffer.Append(request.RequestKey) + buffer.Append(request.ResponseHeader) + buffer.AppendBytes(request.Command) + buffer.Append(request.Address.PortBytes()) switch { case request.Address.IsIPv4(): - buffer = append(buffer, addrTypeIPv4) - buffer = append(buffer, request.Address.IP()...) + buffer.AppendBytes(addrTypeIPv4) + buffer.Append(request.Address.IP()) case request.Address.IsIPv6(): - buffer = append(buffer, addrTypeIPv6) - buffer = append(buffer, request.Address.IP()...) + buffer.AppendBytes(addrTypeIPv6) + buffer.Append(request.Address.IP()) case request.Address.IsDomain(): - buffer = append(buffer, addrTypeDomain) - buffer = append(buffer, byte(len(request.Address.Domain()))) - buffer = append(buffer, []byte(request.Address.Domain())...) + buffer.AppendBytes(addrTypeDomain, byte(len(request.Address.Domain()))) + buffer.Append([]byte(request.Address.Domain())) } - encryptionEnd := len(buffer) + encryptionEnd := buffer.Len() fnv1a := fnv.New32a() - fnv1a.Write(buffer[encryptionBegin:encryptionEnd]) + fnv1a.Write(buffer.Value[encryptionBegin:encryptionEnd]) fnvHash := fnv1a.Sum32() - buffer = append(buffer, byte(fnvHash>>24)) - buffer = append(buffer, byte(fnvHash>>16)) - buffer = append(buffer, byte(fnvHash>>8)) - buffer = append(buffer, byte(fnvHash)) + buffer.AppendBytes(byte(fnvHash>>24), byte(fnvHash>>16), byte(fnvHash>>8), byte(fnvHash)) encryptionEnd += 4 aesCipher, err := aes.NewCipher(request.UserId.CmdKey()) @@ -210,7 +206,7 @@ func (request *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 u return nil, err } aesStream := cipher.NewCFBEncrypter(aesCipher, user.Int64Hash(counter)) - aesStream.XORKeyStream(buffer[encryptionBegin:encryptionEnd], buffer[encryptionBegin:encryptionEnd]) + aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd]) return buffer, nil } diff --git a/proxy/vmess/protocol/vmess_test.go b/proxy/vmess/protocol/vmess_test.go index 8d38eee34..89e6085d1 100644 --- a/proxy/vmess/protocol/vmess_test.go +++ b/proxy/vmess/protocol/vmess_test.go @@ -46,16 +46,17 @@ func TestVMessSerialization(t *testing.T) { request.Address = v2net.DomainAddress("v2ray.com", 80) mockTime := int64(1823730) + buffer, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), func(base int64, delta int) int64 { return mockTime }, nil) if err != nil { t.Fatal(err) } - userSet.UserHashes[string(buffer[:16])] = 0 - userSet.Timestamps[string(buffer[:16])] = mockTime + userSet.UserHashes[string(buffer.Value[:16])] = 0 + userSet.Timestamps[string(buffer.Value[:16])] = mockTime requestReader := NewVMessRequestReader(&userSet) - actualRequest, err := requestReader.Read(bytes.NewReader(buffer)) + actualRequest, err := requestReader.Read(bytes.NewReader(buffer.Value)) if err != nil { t.Fatal(err) } diff --git a/proxy/vmess/vmessout.go b/proxy/vmess/vmessout.go index f45c9b204..788d332ad 100644 --- a/proxy/vmess/vmessout.go +++ b/proxy/vmess/vmessout.go @@ -124,7 +124,7 @@ func handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2 } buffer := alloc.NewBuffer().Clear() - requestBytes, err := request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer.Value) + buffer, err = request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer) if err != nil { log.Error("VMessOut: Failed to serialize VMess request: %v", err) return @@ -140,10 +140,10 @@ func handleRequest(conn net.Conn, request *protocol.VMessRequest, firstPacket v2 if firstChunk != nil { encryptRequestWriter.Crypt(firstChunk.Value) - requestBytes = append(requestBytes, firstChunk.Value...) + buffer.Append(firstChunk.Value) firstChunk.Release() - _, err = conn.Write(requestBytes) + _, err = conn.Write(buffer.Value) buffer.Release() if err != nil { log.Error("VMessOut: Failed to write VMess request: %v", err)