github.com/xmplusdev/xray-core@v1.8.10/common/protocol/server_spec.go (about) 1 package protocol 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/xmplusdev/xray-core/common/dice" 8 "github.com/xmplusdev/xray-core/common/net" 9 ) 10 11 type ValidationStrategy interface { 12 IsValid() bool 13 Invalidate() 14 } 15 16 type alwaysValidStrategy struct{} 17 18 func AlwaysValid() ValidationStrategy { 19 return alwaysValidStrategy{} 20 } 21 22 func (alwaysValidStrategy) IsValid() bool { 23 return true 24 } 25 26 func (alwaysValidStrategy) Invalidate() {} 27 28 type timeoutValidStrategy struct { 29 until time.Time 30 } 31 32 func BeforeTime(t time.Time) ValidationStrategy { 33 return &timeoutValidStrategy{ 34 until: t, 35 } 36 } 37 38 func (s *timeoutValidStrategy) IsValid() bool { 39 return s.until.After(time.Now()) 40 } 41 42 func (s *timeoutValidStrategy) Invalidate() { 43 s.until = time.Time{} 44 } 45 46 type ServerSpec struct { 47 sync.RWMutex 48 dest net.Destination 49 users []*MemoryUser 50 valid ValidationStrategy 51 } 52 53 func NewServerSpec(dest net.Destination, valid ValidationStrategy, users ...*MemoryUser) *ServerSpec { 54 return &ServerSpec{ 55 dest: dest, 56 users: users, 57 valid: valid, 58 } 59 } 60 61 func NewServerSpecFromPB(spec *ServerEndpoint) (*ServerSpec, error) { 62 dest := net.TCPDestination(spec.Address.AsAddress(), net.Port(spec.Port)) 63 mUsers := make([]*MemoryUser, len(spec.User)) 64 for idx, u := range spec.User { 65 mUser, err := u.ToMemoryUser() 66 if err != nil { 67 return nil, err 68 } 69 mUsers[idx] = mUser 70 } 71 return NewServerSpec(dest, AlwaysValid(), mUsers...), nil 72 } 73 74 func (s *ServerSpec) Destination() net.Destination { 75 return s.dest 76 } 77 78 func (s *ServerSpec) HasUser(user *MemoryUser) bool { 79 s.RLock() 80 defer s.RUnlock() 81 82 for _, u := range s.users { 83 if u.Account.Equals(user.Account) { 84 return true 85 } 86 } 87 return false 88 } 89 90 func (s *ServerSpec) AddUser(user *MemoryUser) { 91 if s.HasUser(user) { 92 return 93 } 94 95 s.Lock() 96 defer s.Unlock() 97 98 s.users = append(s.users, user) 99 } 100 101 func (s *ServerSpec) PickUser() *MemoryUser { 102 s.RLock() 103 defer s.RUnlock() 104 105 userCount := len(s.users) 106 switch userCount { 107 case 0: 108 return nil 109 case 1: 110 return s.users[0] 111 default: 112 return s.users[dice.Roll(userCount)] 113 } 114 } 115 116 func (s *ServerSpec) IsValid() bool { 117 return s.valid.IsValid() 118 } 119 120 func (s *ServerSpec) Invalidate() { 121 s.valid.Invalidate() 122 }