vmess.go 6.1 KB

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