validator.go 5.4 KB

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