vmess.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Package vmess contains the implementation of VMess protocol and transportation.
  2. //
  3. // VMess contains both inbound and outbound connections. VMess inbound is usually used on servers
  4. // together with 'freedom' to talk to final destination, while VMess outbound is usually used on
  5. // clients with 'socks' for proxying.
  6. package vmess
  7. //go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg vmess -path Proxy,VMess
  8. import (
  9. "context"
  10. "sync"
  11. "time"
  12. "v2ray.com/core/common/protocol"
  13. )
  14. const (
  15. updateIntervalSec = 10
  16. cacheDurationSec = 120
  17. )
  18. type idEntry struct {
  19. id *protocol.ID
  20. userIdx int
  21. lastSec protocol.Timestamp
  22. lastSecRemoval protocol.Timestamp
  23. }
  24. type TimedUserValidator struct {
  25. sync.RWMutex
  26. ctx context.Context
  27. validUsers []*protocol.User
  28. userHash map[[16]byte]indexTimePair
  29. ids []*idEntry
  30. hasher protocol.IDHash
  31. baseTime protocol.Timestamp
  32. }
  33. type indexTimePair struct {
  34. index int
  35. timeInc uint32
  36. }
  37. func NewTimedUserValidator(ctx context.Context, hasher protocol.IDHash) protocol.UserValidator {
  38. tus := &TimedUserValidator{
  39. ctx: ctx,
  40. validUsers: make([]*protocol.User, 0, 16),
  41. userHash: make(map[[16]byte]indexTimePair, 512),
  42. ids: make([]*idEntry, 0, 512),
  43. hasher: hasher,
  44. baseTime: protocol.Timestamp(time.Now().Unix() - cacheDurationSec*3),
  45. }
  46. go tus.updateUserHash(updateIntervalSec * time.Second)
  47. return tus
  48. }
  49. func (v *TimedUserValidator) generateNewHashes(nowSec protocol.Timestamp, idx int, entry *idEntry) {
  50. var hashValue [16]byte
  51. var hashValueRemoval [16]byte
  52. idHash := v.hasher(entry.id.Bytes())
  53. for entry.lastSec <= nowSec {
  54. idHash.Write(entry.lastSec.Bytes(nil))
  55. idHash.Sum(hashValue[:0])
  56. idHash.Reset()
  57. idHash.Write(entry.lastSecRemoval.Bytes(nil))
  58. idHash.Sum(hashValueRemoval[:0])
  59. idHash.Reset()
  60. delete(v.userHash, hashValueRemoval)
  61. v.userHash[hashValue] = indexTimePair{
  62. index: idx,
  63. timeInc: uint32(entry.lastSec - v.baseTime),
  64. }
  65. entry.lastSec++
  66. entry.lastSecRemoval++
  67. }
  68. }
  69. func (v *TimedUserValidator) updateUserHash(interval time.Duration) {
  70. for {
  71. select {
  72. case now := <-time.After(interval):
  73. nowSec := protocol.Timestamp(now.Unix() + cacheDurationSec)
  74. v.Lock()
  75. for _, entry := range v.ids {
  76. v.generateNewHashes(nowSec, entry.userIdx, entry)
  77. }
  78. v.Unlock()
  79. case <-v.ctx.Done():
  80. return
  81. }
  82. }
  83. }
  84. func (v *TimedUserValidator) Add(user *protocol.User) error {
  85. v.Lock()
  86. defer v.Unlock()
  87. idx := len(v.validUsers)
  88. v.validUsers = append(v.validUsers, user)
  89. rawAccount, err := user.GetTypedAccount()
  90. if err != nil {
  91. return err
  92. }
  93. account := rawAccount.(*InternalAccount)
  94. nowSec := time.Now().Unix()
  95. entry := &idEntry{
  96. id: account.ID,
  97. userIdx: idx,
  98. lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
  99. lastSecRemoval: protocol.Timestamp(nowSec - cacheDurationSec*3),
  100. }
  101. v.generateNewHashes(protocol.Timestamp(nowSec+cacheDurationSec), idx, entry)
  102. v.ids = append(v.ids, entry)
  103. for _, alterid := range account.AlterIDs {
  104. entry := &idEntry{
  105. id: alterid,
  106. userIdx: idx,
  107. lastSec: protocol.Timestamp(nowSec - cacheDurationSec),
  108. lastSecRemoval: protocol.Timestamp(nowSec - cacheDurationSec*3),
  109. }
  110. v.generateNewHashes(protocol.Timestamp(nowSec+cacheDurationSec), idx, entry)
  111. v.ids = append(v.ids, entry)
  112. }
  113. return nil
  114. }
  115. func (v *TimedUserValidator) Get(userHash []byte) (*protocol.User, protocol.Timestamp, bool) {
  116. defer v.RUnlock()
  117. v.RLock()
  118. var fixedSizeHash [16]byte
  119. copy(fixedSizeHash[:], userHash)
  120. pair, found := v.userHash[fixedSizeHash]
  121. if found {
  122. return v.validUsers[pair.index], protocol.Timestamp(pair.timeInc) + v.baseTime, true
  123. }
  124. return nil, 0, false
  125. }