2018-11-07 21:16:13 +00:00
|
|
|
package usermanager
|
|
|
|
|
|
|
|
import (
|
2018-12-29 00:54:10 +00:00
|
|
|
"errors"
|
2018-11-07 21:16:13 +00:00
|
|
|
"net"
|
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
2018-12-29 00:54:10 +00:00
|
|
|
"time"
|
2018-11-08 19:47:53 +00:00
|
|
|
|
|
|
|
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
2018-11-07 21:16:13 +00:00
|
|
|
)
|
|
|
|
|
2018-11-22 21:55:23 +00:00
|
|
|
// for the ease of using json package
|
|
|
|
type UserInfo struct {
|
|
|
|
UID []byte
|
|
|
|
// ALL of the following fields have to be accessed atomically
|
|
|
|
SessionsCap uint32
|
|
|
|
UpRate int64
|
|
|
|
DownRate int64
|
|
|
|
UpCredit int64
|
|
|
|
DownCredit int64
|
|
|
|
ExpiryTime int64
|
2018-11-07 21:16:13 +00:00
|
|
|
}
|
|
|
|
|
2018-11-08 19:47:53 +00:00
|
|
|
type User struct {
|
2018-11-07 21:16:13 +00:00
|
|
|
up *Userpanel
|
|
|
|
|
2019-06-16 01:08:51 +00:00
|
|
|
arrUID [16]byte
|
2018-11-07 21:16:13 +00:00
|
|
|
|
2018-12-08 15:30:46 +00:00
|
|
|
*UserInfo
|
2018-11-07 21:16:13 +00:00
|
|
|
|
|
|
|
valve *mux.Valve
|
|
|
|
|
|
|
|
sessionsM sync.RWMutex
|
|
|
|
sessions map[uint32]*mux.Session
|
|
|
|
}
|
|
|
|
|
2018-12-08 15:30:46 +00:00
|
|
|
func MakeUser(up *Userpanel, uinfo *UserInfo) *User {
|
2018-11-22 21:55:23 +00:00
|
|
|
// this instance of valve is shared across ALL sessions of a user
|
|
|
|
valve := mux.MakeValve(uinfo.UpRate, uinfo.DownRate, &uinfo.UpCredit, &uinfo.DownCredit)
|
2018-11-08 19:47:53 +00:00
|
|
|
u := &User{
|
2018-11-22 21:55:23 +00:00
|
|
|
up: up,
|
|
|
|
UserInfo: uinfo,
|
|
|
|
valve: valve,
|
|
|
|
sessions: make(map[uint32]*mux.Session),
|
2018-11-07 21:16:13 +00:00
|
|
|
}
|
2018-11-22 21:55:23 +00:00
|
|
|
copy(u.arrUID[:], uinfo.UID)
|
2018-11-07 21:16:13 +00:00
|
|
|
return u
|
|
|
|
}
|
|
|
|
|
2018-11-22 21:55:23 +00:00
|
|
|
func (u *User) addUpCredit(delta int64) { u.valve.AddRxCredit(delta) }
|
|
|
|
func (u *User) addDownCredit(delta int64) { u.valve.AddTxCredit(delta) }
|
|
|
|
func (u *User) setSessionsCap(cap uint32) { atomic.StoreUint32(&u.SessionsCap, cap) }
|
|
|
|
func (u *User) setUpRate(rate int64) { u.valve.SetRxRate(rate) }
|
|
|
|
func (u *User) setDownRate(rate int64) { u.valve.SetTxRate(rate) }
|
|
|
|
func (u *User) setUpCredit(n int64) { u.valve.SetRxCredit(n) }
|
|
|
|
func (u *User) setDownCredit(n int64) { u.valve.SetTxCredit(n) }
|
|
|
|
func (u *User) setExpiryTime(time int64) { atomic.StoreInt64(&u.ExpiryTime, time) }
|
|
|
|
|
|
|
|
func (u *User) updateInfo(uinfo UserInfo) {
|
|
|
|
u.setSessionsCap(uinfo.SessionsCap)
|
|
|
|
u.setUpCredit(uinfo.UpCredit)
|
|
|
|
u.setDownCredit(uinfo.DownCredit)
|
|
|
|
u.setUpRate(uinfo.UpRate)
|
|
|
|
u.setDownRate(uinfo.DownRate)
|
|
|
|
u.setExpiryTime(uinfo.ExpiryTime)
|
2018-11-07 21:16:13 +00:00
|
|
|
}
|
|
|
|
|
2018-11-08 19:47:53 +00:00
|
|
|
func (u *User) DelSession(sessionID uint32) {
|
2018-11-07 21:16:13 +00:00
|
|
|
u.sessionsM.Lock()
|
|
|
|
delete(u.sessions, sessionID)
|
|
|
|
if len(u.sessions) == 0 {
|
|
|
|
u.sessionsM.Unlock()
|
2018-11-22 21:55:23 +00:00
|
|
|
u.up.delActiveUser(u.UID)
|
2018-11-07 21:16:13 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
u.sessionsM.Unlock()
|
|
|
|
}
|
|
|
|
|
2018-12-29 00:54:10 +00:00
|
|
|
func (u *User) GetSession(sessionID uint32, obfs mux.Obfser, deobfs mux.Deobfser, obfsedRead func(net.Conn, []byte) (int, error)) (sesh *mux.Session, existing bool, err error) {
|
|
|
|
if time.Now().Unix() > u.ExpiryTime {
|
|
|
|
return nil, false, errors.New("Expiry time passed")
|
|
|
|
}
|
2018-11-08 19:47:53 +00:00
|
|
|
u.sessionsM.Lock()
|
|
|
|
if sesh = u.sessions[sessionID]; sesh != nil {
|
2018-11-24 00:55:26 +00:00
|
|
|
u.sessionsM.Unlock()
|
2018-12-29 00:54:10 +00:00
|
|
|
return sesh, true, nil
|
2018-11-07 21:16:13 +00:00
|
|
|
} else {
|
2018-12-29 00:54:10 +00:00
|
|
|
if len(u.sessions) >= int(u.SessionsCap) {
|
|
|
|
u.sessionsM.Unlock()
|
|
|
|
return nil, false, errors.New("SessionsCap reached")
|
|
|
|
}
|
2018-11-07 21:16:13 +00:00
|
|
|
sesh = mux.MakeSession(sessionID, u.valve, obfs, deobfs, obfsedRead)
|
2018-11-08 19:47:53 +00:00
|
|
|
u.sessions[sessionID] = sesh
|
2018-11-24 00:55:26 +00:00
|
|
|
u.sessionsM.Unlock()
|
2018-12-29 00:54:10 +00:00
|
|
|
return sesh, false, nil
|
2018-11-07 21:16:13 +00:00
|
|
|
}
|
|
|
|
}
|