vmess.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Package vmess contains protocol definition, io lib for VMess.
  2. package protocol
  3. import (
  4. "encoding/binary"
  5. "hash/fnv"
  6. "io"
  7. "time"
  8. "github.com/v2ray/v2ray-core/common/alloc"
  9. v2crypto "github.com/v2ray/v2ray-core/common/crypto"
  10. "github.com/v2ray/v2ray-core/common/log"
  11. v2net "github.com/v2ray/v2ray-core/common/net"
  12. proxyerrors "github.com/v2ray/v2ray-core/proxy/common/errors"
  13. "github.com/v2ray/v2ray-core/proxy/vmess/config"
  14. "github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
  15. "github.com/v2ray/v2ray-core/transport"
  16. )
  17. const (
  18. addrTypeIPv4 = byte(0x01)
  19. addrTypeIPv6 = byte(0x03)
  20. addrTypeDomain = byte(0x02)
  21. CmdTCP = byte(0x01)
  22. CmdUDP = byte(0x02)
  23. Version = byte(0x01)
  24. blockSize = 16
  25. )
  26. // VMessRequest implements the request message of VMess protocol. It only contains the header of a
  27. // request message. The data part will be handled by conection handler directly, in favor of data
  28. // streaming.
  29. type VMessRequest struct {
  30. Version byte
  31. User config.User
  32. RequestIV []byte
  33. RequestKey []byte
  34. ResponseHeader []byte
  35. Command byte
  36. Address v2net.Address
  37. }
  38. // Destination is the final destination of this request.
  39. func (this *VMessRequest) Destination() v2net.Destination {
  40. if this.Command == CmdTCP {
  41. return v2net.NewTCPDestination(this.Address)
  42. } else {
  43. return v2net.NewUDPDestination(this.Address)
  44. }
  45. }
  46. // VMessRequestReader is a parser to read VMessRequest from a byte stream.
  47. type VMessRequestReader struct {
  48. vUserSet user.UserSet
  49. }
  50. // NewVMessRequestReader creates a new VMessRequestReader with a given UserSet
  51. func NewVMessRequestReader(vUserSet user.UserSet) *VMessRequestReader {
  52. return &VMessRequestReader{
  53. vUserSet: vUserSet,
  54. }
  55. }
  56. // Read reads a VMessRequest from a byte stream.
  57. func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
  58. buffer := alloc.NewSmallBuffer()
  59. nBytes, err := v2net.ReadAllBytes(reader, buffer.Value[:config.IDBytesLen])
  60. if err != nil {
  61. return nil, err
  62. }
  63. userObj, timeSec, valid := this.vUserSet.GetUser(buffer.Value[:nBytes])
  64. if !valid {
  65. return nil, proxyerrors.InvalidAuthentication
  66. }
  67. aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID().CmdKey(), user.Int64Hash(timeSec))
  68. if err != nil {
  69. return nil, err
  70. }
  71. decryptor := v2crypto.NewCryptionReader(aesStream, reader)
  72. nBytes, err = v2net.ReadAllBytes(decryptor, buffer.Value[:41])
  73. if err != nil {
  74. return nil, err
  75. }
  76. bufferLen := nBytes
  77. request := &VMessRequest{
  78. User: userObj,
  79. Version: buffer.Value[0],
  80. }
  81. if request.Version != Version {
  82. log.Warning("Invalid protocol version %d", request.Version)
  83. return nil, proxyerrors.InvalidProtocolVersion
  84. }
  85. request.RequestIV = buffer.Value[1:17] // 16 bytes
  86. request.RequestKey = buffer.Value[17:33] // 16 bytes
  87. request.ResponseHeader = buffer.Value[33:37] // 4 bytes
  88. request.Command = buffer.Value[37]
  89. port := binary.BigEndian.Uint16(buffer.Value[38:40])
  90. switch buffer.Value[40] {
  91. case addrTypeIPv4:
  92. _, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:45]) // 4 bytes
  93. bufferLen += 4
  94. if err != nil {
  95. return nil, err
  96. }
  97. request.Address = v2net.IPAddress(buffer.Value[41:45], port)
  98. case addrTypeIPv6:
  99. _, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:57]) // 16 bytes
  100. bufferLen += 16
  101. if err != nil {
  102. return nil, err
  103. }
  104. request.Address = v2net.IPAddress(buffer.Value[41:57], port)
  105. case addrTypeDomain:
  106. _, err = v2net.ReadAllBytes(decryptor, buffer.Value[41:42])
  107. if err != nil {
  108. return nil, err
  109. }
  110. domainLength := int(buffer.Value[41])
  111. _, err = v2net.ReadAllBytes(decryptor, buffer.Value[42:42+domainLength])
  112. if err != nil {
  113. return nil, err
  114. }
  115. bufferLen += 1 + domainLength
  116. request.Address = v2net.DomainAddress(string(buffer.Value[42:42+domainLength]), port)
  117. }
  118. _, err = v2net.ReadAllBytes(decryptor, buffer.Value[bufferLen:bufferLen+4])
  119. if err != nil {
  120. return nil, err
  121. }
  122. fnv1a := fnv.New32a()
  123. fnv1a.Write(buffer.Value[:bufferLen])
  124. actualHash := fnv1a.Sum32()
  125. expectedHash := binary.BigEndian.Uint32(buffer.Value[bufferLen : bufferLen+4])
  126. if actualHash != expectedHash {
  127. return nil, transport.CorruptedPacket
  128. }
  129. return request, nil
  130. }
  131. // ToBytes returns a VMessRequest in the form of byte array.
  132. func (this *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user.RandomInt64InRange, buffer *alloc.Buffer) (*alloc.Buffer, error) {
  133. if buffer == nil {
  134. buffer = alloc.NewSmallBuffer().Clear()
  135. }
  136. counter := randomRangeInt64(time.Now().Unix(), 30)
  137. hash := idHash.Hash(this.User.ID().Bytes[:], counter)
  138. buffer.Append(hash)
  139. encryptionBegin := buffer.Len()
  140. buffer.AppendBytes(this.Version)
  141. buffer.Append(this.RequestIV)
  142. buffer.Append(this.RequestKey)
  143. buffer.Append(this.ResponseHeader)
  144. buffer.AppendBytes(this.Command)
  145. buffer.Append(this.Address.Port().Bytes())
  146. switch {
  147. case this.Address.IsIPv4():
  148. buffer.AppendBytes(addrTypeIPv4)
  149. buffer.Append(this.Address.IP())
  150. case this.Address.IsIPv6():
  151. buffer.AppendBytes(addrTypeIPv6)
  152. buffer.Append(this.Address.IP())
  153. case this.Address.IsDomain():
  154. buffer.AppendBytes(addrTypeDomain, byte(len(this.Address.Domain())))
  155. buffer.Append([]byte(this.Address.Domain()))
  156. }
  157. encryptionEnd := buffer.Len()
  158. fnv1a := fnv.New32a()
  159. fnv1a.Write(buffer.Value[encryptionBegin:encryptionEnd])
  160. fnvHash := fnv1a.Sum32()
  161. buffer.AppendBytes(byte(fnvHash>>24), byte(fnvHash>>16), byte(fnvHash>>8), byte(fnvHash))
  162. encryptionEnd += 4
  163. aesStream, err := v2crypto.NewAesEncryptionStream(this.User.ID().CmdKey(), user.Int64Hash(counter))
  164. if err != nil {
  165. return nil, err
  166. }
  167. aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd])
  168. return buffer, nil
  169. }