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  }