vmess.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Package vmess contains protocol definition, io lib for VMess.
  2. package protocol
  3. import (
  4. "crypto/md5"
  5. "encoding/binary"
  6. "hash/fnv"
  7. "io"
  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. proto "github.com/v2ray/v2ray-core/common/protocol"
  13. "github.com/v2ray/v2ray-core/proxy"
  14. "github.com/v2ray/v2ray-core/transport"
  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. OptionChunk = 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 *proto.User
  32. RequestIV []byte
  33. RequestKey []byte
  34. ResponseHeader byte
  35. Command byte
  36. Option byte
  37. Address v2net.Address
  38. Port v2net.Port
  39. }
  40. // Destination is the final destination of this request.
  41. func (this *VMessRequest) Destination() v2net.Destination {
  42. if this.Command == CmdTCP {
  43. return v2net.TCPDestination(this.Address, this.Port)
  44. } else {
  45. return v2net.UDPDestination(this.Address, this.Port)
  46. }
  47. }
  48. func (this *VMessRequest) IsChunkStream() bool {
  49. return (this.Option & OptionChunk) == OptionChunk
  50. }
  51. // VMessRequestReader is a parser to read VMessRequest from a byte stream.
  52. type VMessRequestReader struct {
  53. vUserSet UserSet
  54. }
  55. // NewVMessRequestReader creates a new VMessRequestReader with a given UserSet
  56. func NewVMessRequestReader(vUserSet UserSet) *VMessRequestReader {
  57. return &VMessRequestReader{
  58. vUserSet: vUserSet,
  59. }
  60. }
  61. // Read reads a VMessRequest from a byte stream.
  62. func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
  63. buffer := alloc.NewSmallBuffer()
  64. defer buffer.Release()
  65. nBytes, err := io.ReadFull(reader, buffer.Value[:proto.IDBytesLen])
  66. if err != nil {
  67. log.Debug("VMess: Failed to read request ID (", nBytes, " bytes): ", err)
  68. return nil, err
  69. }
  70. userObj, timeSec, valid := this.vUserSet.GetUser(buffer.Value[:nBytes])
  71. if !valid {
  72. return nil, proxy.ErrorInvalidAuthentication
  73. }
  74. timestampHash := TimestampHash()
  75. timestampHash.Write(timeSec.HashBytes())
  76. iv := timestampHash.Sum(nil)
  77. aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv)
  78. if err != nil {
  79. log.Debug("VMess: Failed to create AES stream: ", err)
  80. return nil, err
  81. }
  82. decryptor := v2crypto.NewCryptionReader(aesStream, reader)
  83. nBytes, err = io.ReadFull(decryptor, buffer.Value[:41])
  84. if err != nil {
  85. log.Debug("VMess: Failed to read request header (", nBytes, " bytes): ", err)
  86. return nil, err
  87. }
  88. bufferLen := nBytes
  89. request := &VMessRequest{
  90. User: userObj,
  91. Version: buffer.Value[0],
  92. }
  93. if request.Version != Version {
  94. log.Warning("VMess: Invalid protocol version ", request.Version)
  95. return nil, proxy.ErrorInvalidProtocolVersion
  96. }
  97. request.RequestIV = append([]byte(nil), buffer.Value[1:17]...) // 16 bytes
  98. request.RequestKey = append([]byte(nil), buffer.Value[17:33]...) // 16 bytes
  99. request.ResponseHeader = buffer.Value[33] // 1 byte
  100. request.Option = buffer.Value[34] // 1 byte + 2 bytes reserved
  101. request.Command = buffer.Value[37]
  102. request.Port = v2net.PortFromBytes(buffer.Value[38:40])
  103. switch buffer.Value[40] {
  104. case addrTypeIPv4:
  105. nBytes, err = io.ReadFull(decryptor, buffer.Value[41:45]) // 4 bytes
  106. bufferLen += 4
  107. if err != nil {
  108. log.Debug("VMess: Failed to read target IPv4 (", nBytes, " bytes): ", err)
  109. return nil, err
  110. }
  111. request.Address = v2net.IPAddress(buffer.Value[41:45])
  112. case addrTypeIPv6:
  113. nBytes, err = io.ReadFull(decryptor, buffer.Value[41:57]) // 16 bytes
  114. bufferLen += 16
  115. if err != nil {
  116. log.Debug("VMess: Failed to read target IPv6 (", nBytes, " bytes): ", nBytes, err)
  117. return nil, err
  118. }
  119. request.Address = v2net.IPAddress(buffer.Value[41:57])
  120. case addrTypeDomain:
  121. nBytes, err = io.ReadFull(decryptor, buffer.Value[41:42])
  122. if err != nil {
  123. log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
  124. return nil, err
  125. }
  126. domainLength := int(buffer.Value[41])
  127. if domainLength == 0 {
  128. return nil, transport.ErrorCorruptedPacket
  129. }
  130. nBytes, err = io.ReadFull(decryptor, buffer.Value[42:42+domainLength])
  131. if err != nil {
  132. log.Debug("VMess: Failed to read target domain (", nBytes, " bytes): ", nBytes, err)
  133. return nil, err
  134. }
  135. bufferLen += 1 + domainLength
  136. domainBytes := append([]byte(nil), buffer.Value[42:42+domainLength]...)
  137. request.Address = v2net.DomainAddress(string(domainBytes))
  138. }
  139. nBytes, err = io.ReadFull(decryptor, buffer.Value[bufferLen:bufferLen+4])
  140. if err != nil {
  141. log.Debug("VMess: Failed to read checksum (", nBytes, " bytes): ", nBytes, err)
  142. return nil, err
  143. }
  144. fnv1a := fnv.New32a()
  145. fnv1a.Write(buffer.Value[:bufferLen])
  146. actualHash := fnv1a.Sum32()
  147. expectedHash := binary.BigEndian.Uint32(buffer.Value[bufferLen : bufferLen+4])
  148. if actualHash != expectedHash {
  149. return nil, transport.ErrorCorruptedPacket
  150. }
  151. return request, nil
  152. }
  153. // ToBytes returns a VMessRequest in the form of byte array.
  154. func (this *VMessRequest) ToBytes(timestampGenerator RandomTimestampGenerator, buffer *alloc.Buffer) (*alloc.Buffer, error) {
  155. if buffer == nil {
  156. buffer = alloc.NewSmallBuffer().Clear()
  157. }
  158. timestamp := timestampGenerator.Next()
  159. idHash := IDHash(this.User.AnyValidID().Bytes())
  160. idHash.Write(timestamp.Bytes())
  161. hashStart := buffer.Len()
  162. buffer.Slice(0, hashStart+16)
  163. idHash.Sum(buffer.Value[hashStart:hashStart])
  164. encryptionBegin := buffer.Len()
  165. buffer.AppendBytes(this.Version)
  166. buffer.Append(this.RequestIV)
  167. buffer.Append(this.RequestKey)
  168. buffer.AppendBytes(this.ResponseHeader, this.Option, byte(0), byte(0))
  169. buffer.AppendBytes(this.Command)
  170. buffer.Append(this.Port.Bytes())
  171. switch {
  172. case this.Address.IsIPv4():
  173. buffer.AppendBytes(addrTypeIPv4)
  174. buffer.Append(this.Address.IP())
  175. case this.Address.IsIPv6():
  176. buffer.AppendBytes(addrTypeIPv6)
  177. buffer.Append(this.Address.IP())
  178. case this.Address.IsDomain():
  179. buffer.AppendBytes(addrTypeDomain, byte(len(this.Address.Domain())))
  180. buffer.Append([]byte(this.Address.Domain()))
  181. }
  182. encryptionEnd := buffer.Len()
  183. fnv1a := fnv.New32a()
  184. fnv1a.Write(buffer.Value[encryptionBegin:encryptionEnd])
  185. fnvHash := fnv1a.Sum32()
  186. buffer.AppendBytes(byte(fnvHash>>24), byte(fnvHash>>16), byte(fnvHash>>8), byte(fnvHash))
  187. encryptionEnd += 4
  188. timestampHash := md5.New()
  189. timestampHash.Write(timestamp.HashBytes())
  190. iv := timestampHash.Sum(nil)
  191. aesStream, err := v2crypto.NewAesEncryptionStream(this.User.ID.CmdKey(), iv)
  192. if err != nil {
  193. return nil, err
  194. }
  195. aesStream.XORKeyStream(buffer.Value[encryptionBegin:encryptionEnd], buffer.Value[encryptionBegin:encryptionEnd])
  196. return buffer, nil
  197. }