func (v *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) { timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)() account, err := header.User.GetTypedAccount() if err != nil { log.Error("VMess: Failed to get user account: ", err) return } idHash := v.idHash(account.(*vmess.InternalAccount).AnyValidID().Bytes()) idHash.Write(timestamp.Bytes(nil)) writer.Write(idHash.Sum(nil)) buffer := make([]byte, 0, 512) buffer = append(buffer, Version) buffer = append(buffer, v.requestBodyIV...) buffer = append(buffer, v.requestBodyKey...) buffer = append(buffer, v.responseHeader, byte(header.Option)) padingLen := dice.Roll(16) if header.Security.Is(protocol.SecurityType_LEGACY) { // Disable padding in legacy mode for a smooth transition. padingLen = 0 } security := byte(padingLen<<4) | byte(header.Security) buffer = append(buffer, security, byte(0), byte(header.Command)) buffer = header.Port.Bytes(buffer) switch header.Address.Family() { case v2net.AddressFamilyIPv4: buffer = append(buffer, AddrTypeIPv4) buffer = append(buffer, header.Address.IP()...) case v2net.AddressFamilyIPv6: buffer = append(buffer, AddrTypeIPv6) buffer = append(buffer, header.Address.IP()...) case v2net.AddressFamilyDomain: buffer = append(buffer, AddrTypeDomain, byte(len(header.Address.Domain()))) buffer = append(buffer, header.Address.Domain()...) } if padingLen > 0 { pading := make([]byte, padingLen) rand.Read(pading) buffer = append(buffer, pading...) } fnv1a := fnv.New32a() fnv1a.Write(buffer) buffer = fnv1a.Sum(buffer) timestampHash := md5.New() timestampHash.Write(hashTimestamp(timestamp)) iv := timestampHash.Sum(nil) aesStream := crypto.NewAesEncryptionStream(account.(*vmess.InternalAccount).ID.CmdKey(), iv) aesStream.XORKeyStream(buffer, buffer) writer.Write(buffer) return }
func (this *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writer io.Writer) { timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)() account, err := header.User.GetTypedAccount() if err != nil { log.Error("VMess: Failed to get user account: ", err) return } idHash := this.idHash(account.(*vmess.InternalAccount).AnyValidID().Bytes()) idHash.Write(timestamp.Bytes(nil)) writer.Write(idHash.Sum(nil)) buffer := make([]byte, 0, 512) buffer = append(buffer, Version) buffer = append(buffer, this.requestBodyIV...) buffer = append(buffer, this.requestBodyKey...) buffer = append(buffer, this.responseHeader, byte(header.Option), byte(0), byte(0), byte(header.Command)) buffer = header.Port.Bytes(buffer) switch header.Address.Family() { case v2net.AddressFamilyIPv4: buffer = append(buffer, AddrTypeIPv4) buffer = append(buffer, header.Address.IP()...) case v2net.AddressFamilyIPv6: buffer = append(buffer, AddrTypeIPv6) buffer = append(buffer, header.Address.IP()...) case v2net.AddressFamilyDomain: buffer = append(buffer, AddrTypeDomain, byte(len(header.Address.Domain()))) buffer = append(buffer, header.Address.Domain()...) } fnv1a := fnv.New32a() fnv1a.Write(buffer) buffer = fnv1a.Sum(buffer) timestampHash := md5.New() timestampHash.Write(hashTimestamp(timestamp)) iv := timestampHash.Sum(nil) aesStream := crypto.NewAesEncryptionStream(account.(*vmess.InternalAccount).ID.CmdKey(), iv) aesStream.XORKeyStream(buffer, buffer) writer.Write(buffer) return }