diff --git a/common/serial/bytes.go b/common/serial/bytes.go index a9295bcdb..ebbfa7591 100644 --- a/common/serial/bytes.go +++ b/common/serial/bytes.go @@ -10,6 +10,14 @@ func (this BytesLiteral) Value() []byte { return []byte(this) } +func (this BytesLiteral) Uint32Value() uint32 { + value := this.Value() + return uint32(value[0])<<24 + + uint32(value[1])<<16 + + uint32(value[2])<<8 + + uint32(value[3]) +} + func (this BytesLiteral) Int64Value() int64 { value := this.Value() return int64(value[0])<<56 + diff --git a/proxy/vmess/inbound/command.go b/proxy/vmess/inbound/command.go index 8e713df11..bc2aa38b0 100644 --- a/proxy/vmess/inbound/command.go +++ b/proxy/vmess/inbound/command.go @@ -1,6 +1,8 @@ package inbound import ( + "hash/fnv" + "github.com/v2ray/v2ray-core/common/alloc" "github.com/v2ray/v2ray-core/common/log" "github.com/v2ray/v2ray-core/common/serial" @@ -38,10 +40,14 @@ func (this *VMessInboundHandler) generateCommand(buffer *alloc.Buffer) { } } - if commandBytes.Len() > 256 { + if cmd == 0 || commandBytes.Len()+4 > 256 { buffer.AppendBytes(byte(0), byte(0)) } else { - buffer.AppendBytes(cmd, byte(commandBytes.Len())) + buffer.AppendBytes(cmd, byte(commandBytes.Len()+4)) + fnv1hash := fnv.New32a() + fnv1hash.Write(commandBytes.Value) + hashValue := fnv1hash.Sum32() + buffer.AppendBytes(byte(hashValue>>24), byte(hashValue>>16), byte(hashValue>>8), byte(hashValue)) buffer.Append(commandBytes.Value) } } diff --git a/proxy/vmess/outbound/command.go b/proxy/vmess/outbound/command.go index 868f61a74..3f6bf5aca 100644 --- a/proxy/vmess/outbound/command.go +++ b/proxy/vmess/outbound/command.go @@ -1,8 +1,11 @@ package outbound import ( + "hash/fnv" + "github.com/v2ray/v2ray-core/common/log" v2net "github.com/v2ray/v2ray-core/common/net" + "github.com/v2ray/v2ray-core/common/serial" "github.com/v2ray/v2ray-core/proxy/vmess" "github.com/v2ray/v2ray-core/proxy/vmess/command" ) @@ -14,6 +17,17 @@ func (this *VMessOutboundHandler) handleSwitchAccount(cmd *command.SwitchAccount } func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmdId byte, data []byte) { + if len(data) < 4 { + return + } + fnv1hash := fnv.New32a() + fnv1hash.Write(data[4:]) + actualHashValue := fnv1hash.Sum32() + expectedHashValue := serial.BytesLiteral(data[:4]).Uint32Value() + if actualHashValue != expectedHashValue { + return + } + data = data[4:] cmd, err := command.CreateResponseCommand(cmdId) if err != nil { log.Warning("VMessOut: Unknown response command (", cmdId, "): ", err)