validator.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // +build !confonly
  2. package vmess
  3. import (
  4. "crypto/hmac"
  5. "crypto/sha256"
  6. "hash/crc64"
  7. "strings"
  8. "sync"
  9. "sync/atomic"
  10. "time"
  11. "v2ray.com/core/common"
  12. "v2ray.com/core/common/dice"
  13. "v2ray.com/core/common/protocol"
  14. "v2ray.com/core/common/serial"
  15. "v2ray.com/core/common/task"
  16. "v2ray.com/core/proxy/vmess/aead"
  17. )
  18. const (
  19. updateInterval = 10 * time.Second
  20. cacheDurationSec = 120
  21. )
  22. type user struct {
  23. user protocol.MemoryUser
  24. lastSec protocol.Timestamp
  25. }
  26. // TimedUserValidator is a user Validator based on time.
  27. type TimedUserValidator struct {
  28. sync.RWMutex
  29. users []*user
  30. userHash map[[16]byte]indexTimePair
  31. hasher protocol.IDHash
  32. baseTime protocol.Timestamp
  33. task *task.Periodic
  34. behaviorSeed uint64
  35. behaviorFused bool
  36. aeadDecoderHolder *aead.AuthIDDecoderHolder
  37. }
  38. type indexTimePair struct {
  39. user *user
  40. timeInc uint32
  41. taintedFuse *uint32
  42. }
  43. // NewTimedUserValidator creates a new TimedUserValidator.
  44. func NewTimedUserValidator(hasher protocol.IDHash) *TimedUserValidator {
  45. tuv := &TimedUserValidator{
  46. users: make([]*user, 0, 16),
  47. userHash: make(map[[16]byte]indexTimePair, 1024),
  48. hasher: hasher,
  49. baseTime: protocol.Timestamp(time.Now().Unix() - cacheDurationSec*2),
  50. aeadDecoderHolder: aead.NewAuthIDDecoderHolder(),
  51. }
  52. tuv.task = &task.Periodic{
  53. Interval: updateInterval,
  54. Execute: func() error {
  55. tuv.updateUserHash()
  56. return nil
  57. },
  58. }
  59. common.Must(tuv.task.Start())
  60. return tuv
  61. }
  62. func (v *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, user *user) {
  63. var hashValue [16]byte
  64. genEndSec := nowSec + cacheDurationSec
  65. genHashForID := func(id *protocol.ID) {
  66. idHash := v.hasher(id.Bytes())
  67. genBeginSec := user.lastSec
  68. if genBeginSec < nowSec-cacheDurationSec {
  69. genBeginSec = nowSec - cacheDurationSec
  70. }
  71. for ts := genBeginSec; ts <= genEndSec; ts++ {
  72. common.Must2(serial.WriteUint64(idHash, uint64(ts)))
  73. idHash.Sum(hashValue[:0])
  74. idHash.Reset()
  75. v.userHash[hashValue] = indexTimePair{
  76. user: user,
  77. timeInc: uint32(ts - v.baseTime),
  78. taintedFuse: new(uint32),
  79. }
  80. }
  81. }
  82. account := user.user.Account.(*MemoryAccount)
  83. genHashForID(account.ID)
  84. for _, id := range account.AlterIDs {
  85. genHashForID(id)
  86. }
  87. user.lastSec = genEndSec
  88. }
  89. func (v *TimedUserValidator) removeExpiredHashes(expire uint32) {
  90. for key, pair := range v.userHash {
  91. if pair.timeInc < expire {
  92. delete(v.userHash, key)
  93. }
  94. }
  95. }
  96. func (v *TimedUserValidator) updateUserHash() {
  97. now := time.Now()
  98. nowSec := protocol.Timestamp(now.Unix())
  99. v.Lock()
  100. defer v.Unlock()
  101. for _, user := range v.users {
  102. v.generateNewHashes(nowSec, user)
  103. }
  104. expire := protocol.Timestamp(now.Unix() - cacheDurationSec)
  105. if expire > v.baseTime {
  106. v.removeExpiredHashes(uint32(expire - v.baseTime))
  107. }
  108. }
  109. func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
  110. v.Lock()
  111. defer v.Unlock()
  112. nowSec := time.Now().Unix()
  113. uu := &user{
  114. user: *u,
  115. lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
  116. }
  117. v.users = append(v.users, uu)
  118. v.generateNewHashes(protocol.Timestamp(nowSec), uu)
  119. account := uu.user.Account.(*MemoryAccount)
  120. if !v.behaviorFused {
  121. hashkdf := hmac.New(sha256.New, []byte("VMESSBSKDF"))
  122. hashkdf.Write(account.ID.Bytes())
  123. v.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil))
  124. }
  125. var cmdkeyfl [16]byte
  126. copy(cmdkeyfl[:], account.ID.CmdKey())
  127. v.aeadDecoderHolder.AddUser(cmdkeyfl, u)
  128. return nil
  129. }
  130. func (v *TimedUserValidator) Get(userHash []byte) (*protocol.MemoryUser, protocol.Timestamp, bool, error) {
  131. defer v.RUnlock()
  132. v.RLock()
  133. v.behaviorFused = true
  134. var fixedSizeHash [16]byte
  135. copy(fixedSizeHash[:], userHash)
  136. pair, found := v.userHash[fixedSizeHash]
  137. if found {
  138. user := pair.user.user
  139. if atomic.LoadUint32(pair.taintedFuse) == 0 {
  140. return &user, protocol.Timestamp(pair.timeInc) + v.baseTime, true, nil
  141. }
  142. return nil, 0, false, ErrTainted
  143. }
  144. return nil, 0, false, ErrNotFound
  145. }
  146. func (v *TimedUserValidator) GetAEAD(userHash []byte) (*protocol.MemoryUser, bool, error) {
  147. defer v.RUnlock()
  148. v.RLock()
  149. var userHashFL [16]byte
  150. copy(userHashFL[:], userHash)
  151. userd, err := v.aeadDecoderHolder.Match(userHashFL)
  152. if err != nil {
  153. return nil, false, err
  154. }
  155. return userd.(*protocol.MemoryUser), true, err
  156. }
  157. func (v *TimedUserValidator) Remove(email string) bool {
  158. v.Lock()
  159. defer v.Unlock()
  160. email = strings.ToLower(email)
  161. idx := -1
  162. for i, u := range v.users {
  163. if strings.EqualFold(u.user.Email, email) {
  164. idx = i
  165. var cmdkeyfl [16]byte
  166. copy(cmdkeyfl[:], u.user.Account.(*MemoryAccount).ID.CmdKey())
  167. v.aeadDecoderHolder.RemoveUser(cmdkeyfl)
  168. break
  169. }
  170. }
  171. if idx == -1 {
  172. return false
  173. }
  174. ulen := len(v.users)
  175. v.users[idx] = v.users[ulen-1]
  176. v.users[ulen-1] = nil
  177. v.users = v.users[:ulen-1]
  178. return true
  179. }
  180. // Close implements common.Closable.
  181. func (v *TimedUserValidator) Close() error {
  182. return v.task.Close()
  183. }
  184. func (v *TimedUserValidator) GetBehaviorSeed() uint64 {
  185. v.Lock()
  186. defer v.Unlock()
  187. v.behaviorFused = true
  188. if v.behaviorSeed == 0 {
  189. v.behaviorSeed = dice.RollUint64()
  190. }
  191. return v.behaviorSeed
  192. }
  193. func (v *TimedUserValidator) BurnTaintFuse(userHash []byte) error {
  194. v.RLock()
  195. defer v.RUnlock()
  196. var userHashFL [16]byte
  197. copy(userHashFL[:], userHash)
  198. pair, found := v.userHash[userHashFL]
  199. if found {
  200. if atomic.CompareAndSwapUint32(pair.taintedFuse, 0, 1) {
  201. return nil
  202. }
  203. return ErrTainted
  204. }
  205. return ErrNotFound
  206. }
  207. var ErrNotFound = newError("Not Found")
  208. var ErrTainted = newError("ErrTainted")