فهرست منبع

Introduce user level

V2Ray 10 سال پیش
والد
کامیت
b44098d752

+ 7 - 0
proxy/vmess/config/json/user.go

@@ -10,12 +10,14 @@ import (
 type ConfigUser struct {
 	Id    *config.ID
 	Email string
+  LevelValue config.UserLevel
 }
 
 func (u *ConfigUser) UnmarshalJSON(data []byte) error {
 	type rawUser struct {
 		IdString    string `json:"id"`
 		EmailString string `json:"email"`
+    LevelInt int `json:"level"`
 	}
 	var rawUserValue rawUser
 	if err := json.Unmarshal(data, &rawUserValue); err != nil {
@@ -27,9 +29,14 @@ func (u *ConfigUser) UnmarshalJSON(data []byte) error {
 	}
 	u.Id = id
 	u.Email = rawUserValue.EmailString
+  u.LevelValue = config.UserLevel(rawUserValue.LevelInt)
 	return nil
 }
 
 func (u *ConfigUser) ID() *config.ID {
 	return u.Id
 }
+
+func (this *ConfigUser) Level() config.UserLevel {
+  return this.LevelValue
+}

+ 22 - 0
proxy/vmess/config/user.go

@@ -1,5 +1,27 @@
 package config
 
+type UserLevel int
+
+const (
+  UserLevelAdmin = UserLevel(999)
+  UserLevelUntrusted = UserLevel(0)
+)
+
 type User interface {
 	ID() *ID
+  Level() UserLevel
+}
+
+type UserSettings struct {
+  PayloadReadTimeout int
+}
+
+func GetUserSettings(level UserLevel) UserSettings {
+  settings := UserSettings {
+    PayloadReadTimeout: 120,
+  }
+  if level > 0 {
+    settings.PayloadReadTimeout = 0
+  }
+  return settings
 }

+ 9 - 9
proxy/vmess/protocol/user/userset.go

@@ -15,11 +15,11 @@ const (
 
 type UserSet interface {
 	AddUser(user config.User) error
-	GetUser(timeHash []byte) (*config.ID, int64, bool)
+	GetUser(timeHash []byte) (config.User, int64, bool)
 }
 
 type TimedUserSet struct {
-	validUserIds        []*config.ID
+	validUsers        []config.User
 	userHash            map[string]indexTimePair
 	userHashDeleteQueue *collect.TimedQueue
 	access              sync.RWMutex
@@ -32,7 +32,7 @@ type indexTimePair struct {
 
 func NewTimedUserSet() UserSet {
 	tus := &TimedUserSet{
-		validUserIds:        make([]*config.ID, 0, 16),
+		validUsers:        make([]config.User, 0, 16),
 		userHash:            make(map[string]indexTimePair, 512),
 		userHashDeleteQueue: collect.NewTimedQueue(updateIntervalSec),
 		access:              sync.RWMutex{},
@@ -67,8 +67,8 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
 
 	for now := range tick {
 		nowSec := now.Unix() + cacheDurationSec
-		for idx, id := range us.validUserIds {
-			us.generateNewHashes(lastSec, nowSec, idx, id)
+		for idx, user := range us.validUsers {
+			us.generateNewHashes(lastSec, nowSec, idx, user.ID())
 		}
 		lastSec = nowSec
 	}
@@ -76,8 +76,8 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
 
 func (us *TimedUserSet) AddUser(user config.User) error {
 	id := user.ID()
-	idx := len(us.validUserIds)
-	us.validUserIds = append(us.validUserIds, id)
+	idx := len(us.validUsers)
+	us.validUsers = append(us.validUsers, user)
 
 	nowSec := time.Now().Unix()
 	lastSec := nowSec - cacheDurationSec
@@ -86,12 +86,12 @@ func (us *TimedUserSet) AddUser(user config.User) error {
 	return nil
 }
 
-func (us TimedUserSet) GetUser(userHash []byte) (*config.ID, int64, bool) {
+func (us TimedUserSet) GetUser(userHash []byte) (config.User, int64, bool) {
 	defer us.access.RUnlock()
 	us.access.RLock()
 	pair, found := us.userHash[string(userHash)]
 	if found {
-		return us.validUserIds[pair.index], pair.timeSec, true
+		return us.validUsers[pair.index], pair.timeSec, true
 	}
 	return nil, 0, false
 }

+ 3 - 3
proxy/vmess/protocol/vmess.go

@@ -75,12 +75,12 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 		return nil, err
 	}
 
-	userId, timeSec, valid := r.vUserSet.GetUser(buffer.Value[:nBytes])
+	userObj, timeSec, valid := r.vUserSet.GetUser(buffer.Value[:nBytes])
 	if !valid {
 		return nil, proxyerrors.InvalidAuthentication
 	}
 
-	aesCipher, err := aes.NewCipher(userId.CmdKey())
+	aesCipher, err := aes.NewCipher(userObj.ID().CmdKey())
 	if err != nil {
 		return nil, err
 	}
@@ -98,7 +98,7 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 	bufferLen := nBytes
 
 	request := &VMessRequest{
-		UserId:  *userId,
+		UserId:  *userObj.ID(),
 		Version: buffer.Value[0],
 	}
 

+ 13 - 4
proxy/vmess/protocol/vmess_test.go

@@ -14,12 +14,17 @@ import (
 
 type TestUser struct {
 	id *config.ID
+  level config.UserLevel
 }
 
 func (u *TestUser) ID() *config.ID {
 	return u.id
 }
 
+func (this *TestUser) Level() config.UserLevel {
+  return this.level
+}
+
 func TestVMessSerialization(t *testing.T) {
 	assert := unit.Assert(t)
 
@@ -28,8 +33,10 @@ func TestVMessSerialization(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	userSet := mocks.MockUserSet{[]*config.ID{}, make(map[string]int), make(map[string]int64)}
-	userSet.AddUser(&TestUser{userId})
+	userSet := mocks.MockUserSet{[]config.User{}, make(map[string]int), make(map[string]int64)}
+	userSet.AddUser(&TestUser{
+    id: userId,
+  })
 
 	request := new(VMessRequest)
 	request.Version = byte(0x01)
@@ -72,8 +79,10 @@ func TestVMessSerialization(t *testing.T) {
 
 func BenchmarkVMessRequestWriting(b *testing.B) {
 	userId, _ := config.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
-	userSet := mocks.MockUserSet{[]*config.ID{}, make(map[string]int), make(map[string]int64)}
-	userSet.AddUser(&TestUser{userId})
+	userSet := mocks.MockUserSet{[]config.User{}, make(map[string]int), make(map[string]int64)}
+	userSet.AddUser(&TestUser{
+    id: userId,
+  })
 
 	request := new(VMessRequest)
 	request.Version = byte(0x01)

+ 4 - 4
testing/mocks/mockuserset.go

@@ -5,20 +5,20 @@ import (
 )
 
 type MockUserSet struct {
-	UserIds    []*config.ID
+	Users    []config.User
 	UserHashes map[string]int
 	Timestamps map[string]int64
 }
 
 func (us *MockUserSet) AddUser(user config.User) error {
-	us.UserIds = append(us.UserIds, user.ID())
+	us.Users = append(us.Users, user)
 	return nil
 }
 
-func (us *MockUserSet) GetUser(userhash []byte) (*config.ID, int64, bool) {
+func (us *MockUserSet) GetUser(userhash []byte) (config.User, int64, bool) {
 	idx, found := us.UserHashes[string(userhash)]
 	if found {
-		return us.UserIds[idx], us.Timestamps[string(userhash)], true
+		return us.Users[idx], us.Timestamps[string(userhash)], true
 	}
 	return nil, 0, false
 }