validator.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // +build !confonly
  2. package vmess
  3. import (
  4. "strings"
  5. "sync"
  6. "time"
  7. "v2ray.com/core/common"
  8. "v2ray.com/core/common/protocol"
  9. "v2ray.com/core/common/serial"
  10. "v2ray.com/core/common/task"
  11. )
  12. const (
  13. updateInterval = 10 * time.Second
  14. cacheDurationSec = 120
  15. )
  16. type user struct {
  17. user protocol.MemoryUser
  18. lastSec protocol.Timestamp
  19. }
  20. // TimedUserValidator is a user Validator based on time.
  21. type TimedUserValidator struct {
  22. sync.RWMutex
  23. users []*user
  24. userHash map[[16]byte]indexTimePair
  25. hasher protocol.IDHash
  26. baseTime protocol.Timestamp
  27. task *task.Periodic
  28. }
  29. type indexTimePair struct {
  30. user *user
  31. timeInc uint32
  32. }
  33. // NewTimedUserValidator creates a new TimedUserValidator.
  34. func NewTimedUserValidator(hasher protocol.IDHash) *TimedUserValidator {
  35. tuv := &TimedUserValidator{
  36. users: make([]*user, 0, 16),
  37. userHash: make(map[[16]byte]indexTimePair, 1024),
  38. hasher: hasher,
  39. baseTime: protocol.Timestamp(time.Now().Unix() - cacheDurationSec*2),
  40. }
  41. tuv.task = &task.Periodic{
  42. Interval: updateInterval,
  43. Execute: func() error {
  44. tuv.updateUserHash()
  45. return nil
  46. },
  47. }
  48. common.Must(tuv.task.Start())
  49. return tuv
  50. }
  51. func (v *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, user *user) {
  52. var hashValue [16]byte
  53. genEndSec := nowSec + cacheDurationSec
  54. genHashForID := func(id *protocol.ID) {
  55. idHash := v.hasher(id.Bytes())
  56. genBeginSec := user.lastSec
  57. if genBeginSec < nowSec-cacheDurationSec {
  58. genBeginSec = nowSec - cacheDurationSec
  59. }
  60. for ts := genBeginSec; ts <= genEndSec; ts++ {
  61. common.Must2(serial.WriteUint64(idHash, uint64(ts)))
  62. idHash.Sum(hashValue[:0])
  63. idHash.Reset()
  64. v.userHash[hashValue] = indexTimePair{
  65. user: user,
  66. timeInc: uint32(ts - v.baseTime),
  67. }
  68. }
  69. }
  70. account := user.user.Account.(*MemoryAccount)
  71. genHashForID(account.ID)
  72. for _, id := range account.AlterIDs {
  73. genHashForID(id)
  74. }
  75. user.lastSec = genEndSec
  76. }
  77. func (v *TimedUserValidator) removeExpiredHashes(expire uint32) {
  78. for key, pair := range v.userHash {
  79. if pair.timeInc < expire {
  80. delete(v.userHash, key)
  81. }
  82. }
  83. }
  84. func (v *TimedUserValidator) updateUserHash() {
  85. now := time.Now()
  86. nowSec := protocol.Timestamp(now.Unix())
  87. v.Lock()
  88. defer v.Unlock()
  89. for _, user := range v.users {
  90. v.generateNewHashes(nowSec, user)
  91. }
  92. expire := protocol.Timestamp(now.Unix() - cacheDurationSec)
  93. if expire > v.baseTime {
  94. v.removeExpiredHashes(uint32(expire - v.baseTime))
  95. }
  96. }
  97. func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
  98. v.Lock()
  99. defer v.Unlock()
  100. nowSec := time.Now().Unix()
  101. uu := &user{
  102. user: *u,
  103. lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
  104. }
  105. v.users = append(v.users, uu)
  106. v.generateNewHashes(protocol.Timestamp(nowSec), uu)
  107. return nil
  108. }
  109. func (v *TimedUserValidator) Get(userHash []byte) (*protocol.MemoryUser, protocol.Timestamp, bool) {
  110. defer v.RUnlock()
  111. v.RLock()
  112. var fixedSizeHash [16]byte
  113. copy(fixedSizeHash[:], userHash)
  114. pair, found := v.userHash[fixedSizeHash]
  115. if found {
  116. var user protocol.MemoryUser
  117. user = pair.user.user
  118. return &user, protocol.Timestamp(pair.timeInc) + v.baseTime, true
  119. }
  120. return nil, 0, false
  121. }
  122. func (v *TimedUserValidator) Remove(email string) bool {
  123. v.Lock()
  124. defer v.Unlock()
  125. email = strings.ToLower(email)
  126. idx := -1
  127. for i, u := range v.users {
  128. if strings.EqualFold(u.user.Email, email) {
  129. idx = i
  130. break
  131. }
  132. }
  133. if idx == -1 {
  134. return false
  135. }
  136. ulen := len(v.users)
  137. v.users[idx] = v.users[ulen-1]
  138. v.users[ulen-1] = nil
  139. v.users = v.users[:ulen-1]
  140. return true
  141. }
  142. // Close implements common.Closable.
  143. func (v *TimedUserValidator) Close() error {
  144. return v.task.Close()
  145. }