validator.go 5.3 KB

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