udp.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package protocol
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "encoding/binary"
  6. "hash/fnv"
  7. "time"
  8. "github.com/v2ray/v2ray-core/common/errors"
  9. "github.com/v2ray/v2ray-core/common/log"
  10. v2net "github.com/v2ray/v2ray-core/common/net"
  11. "github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
  12. )
  13. type VMessUDP struct {
  14. user user.ID
  15. version byte
  16. address v2net.Address
  17. data []byte
  18. }
  19. func (message *VMessUDP) ToPacket() v2net.Packet {
  20. dest := v2net.NewUDPDestination(message.address)
  21. return v2net.NewPacket(dest, message.data, false)
  22. }
  23. func ReadVMessUDP(buffer []byte, userset user.UserSet) (*VMessUDP, error) {
  24. userHash := buffer[:user.IDBytesLen]
  25. userId, timeSec, valid := userset.GetUser(userHash)
  26. if !valid {
  27. return nil, errors.NewAuthenticationError(userHash)
  28. }
  29. buffer = buffer[user.IDBytesLen:]
  30. aesCipher, err := aes.NewCipher(userId.CmdKey())
  31. if err != nil {
  32. return nil, err
  33. }
  34. aesStream := cipher.NewCFBDecrypter(aesCipher, user.Int64Hash(timeSec))
  35. aesStream.XORKeyStream(buffer, buffer)
  36. fnvHash := binary.BigEndian.Uint32(buffer[:4])
  37. fnv1a := fnv.New32a()
  38. fnv1a.Write(buffer[4:])
  39. fnvHashActual := fnv1a.Sum32()
  40. if fnvHash != fnvHashActual {
  41. log.Warning("Unexpected fhv hash %d, should be %d", fnvHashActual, fnvHash)
  42. return nil, errors.NewCorruptedPacketError()
  43. }
  44. buffer = buffer[4:]
  45. vmess := &VMessUDP{
  46. user: *userId,
  47. version: buffer[0],
  48. }
  49. // buffer[1] is reserved
  50. port := binary.BigEndian.Uint16(buffer[2:4])
  51. addrType := buffer[4]
  52. var address v2net.Address
  53. switch addrType {
  54. case addrTypeIPv4:
  55. address = v2net.IPAddress(buffer[5:9], port)
  56. buffer = buffer[9:]
  57. case addrTypeIPv6:
  58. address = v2net.IPAddress(buffer[5:21], port)
  59. buffer = buffer[21:]
  60. case addrTypeDomain:
  61. domainLength := buffer[5]
  62. domain := string(buffer[6 : 6+domainLength])
  63. address = v2net.DomainAddress(domain, port)
  64. buffer = buffer[6+domainLength:]
  65. default:
  66. log.Warning("Unexpected address type %d", addrType)
  67. return nil, errors.NewCorruptedPacketError()
  68. }
  69. vmess.address = address
  70. vmess.data = buffer
  71. return vmess, nil
  72. }
  73. func (vmess *VMessUDP) ToBytes(idHash user.CounterHash, randomRangeInt64 user.RandomInt64InRange, buffer []byte) []byte {
  74. if buffer == nil {
  75. buffer = make([]byte, 0, 2*1024)
  76. }
  77. counter := randomRangeInt64(time.Now().UTC().Unix(), 30)
  78. hash := idHash.Hash(vmess.user.Bytes[:], counter)
  79. buffer = append(buffer, hash...)
  80. encryptBegin := 16
  81. // Placeholder for fnv1a hash
  82. buffer = append(buffer, byte(0), byte(0), byte(0), byte(0))
  83. fnvHash := 16
  84. fnvHashBegin := 20
  85. buffer = append(buffer, vmess.version)
  86. buffer = append(buffer, byte(0x00))
  87. buffer = append(buffer, vmess.address.PortBytes()...)
  88. switch {
  89. case vmess.address.IsIPv4():
  90. buffer = append(buffer, addrTypeIPv4)
  91. buffer = append(buffer, vmess.address.IP()...)
  92. case vmess.address.IsIPv6():
  93. buffer = append(buffer, addrTypeIPv6)
  94. buffer = append(buffer, vmess.address.IP()...)
  95. case vmess.address.IsDomain():
  96. buffer = append(buffer, addrTypeDomain)
  97. buffer = append(buffer, byte(len(vmess.address.Domain())))
  98. buffer = append(buffer, []byte(vmess.address.Domain())...)
  99. }
  100. buffer = append(buffer, vmess.data...)
  101. fnv1a := fnv.New32a()
  102. fnv1a.Write(buffer[fnvHashBegin:])
  103. fnvHashValue := fnv1a.Sum32()
  104. buffer[fnvHash] = byte(fnvHashValue >> 24)
  105. buffer[fnvHash+1] = byte(fnvHashValue >> 16)
  106. buffer[fnvHash+2] = byte(fnvHashValue >> 8)
  107. buffer[fnvHash+3] = byte(fnvHashValue)
  108. aesCipher, err := aes.NewCipher(vmess.user.CmdKey())
  109. if err != nil {
  110. log.Error("VMess failed to create AES cipher: %v", err)
  111. return nil
  112. }
  113. aesStream := cipher.NewCFBEncrypter(aesCipher, user.Int64Hash(counter))
  114. aesStream.XORKeyStream(buffer[encryptBegin:], buffer[encryptBegin:])
  115. return buffer
  116. }