github.com/ipfans/trojan-go@v0.11.0/statistic/statistics.go (about) 1 package statistic 2 3 import ( 4 "context" 5 "io" 6 "strings" 7 "sync" 8 9 "github.com/ipfans/trojan-go/common" 10 "github.com/ipfans/trojan-go/log" 11 ) 12 13 type TrafficMeter interface { 14 io.Closer 15 Hash() string 16 AddTraffic(sent, recv int) 17 GetTraffic() (sent, recv uint64) 18 SetTraffic(sent, recv uint64) 19 ResetTraffic() (sent, recv uint64) 20 GetSpeed() (sent, recv uint64) 21 GetSpeedLimit() (sent, recv int) 22 SetSpeedLimit(sent, recv int) 23 } 24 25 type IPRecorder interface { 26 AddIP(string) bool 27 DelIP(string) bool 28 GetIP() int 29 SetIPLimit(int) 30 GetIPLimit() int 31 } 32 33 type User interface { 34 TrafficMeter 35 IPRecorder 36 } 37 38 type Authenticator interface { 39 io.Closer 40 AuthUser(hash string) (valid bool, user User) 41 AddUser(hash string) error 42 DelUser(hash string) error 43 ListUsers() []User 44 } 45 46 type Creator func(ctx context.Context) (Authenticator, error) 47 48 var ( 49 createdAuthLock sync.Mutex 50 authCreators = make(map[string]Creator) 51 createdAuth = make(map[context.Context]Authenticator) 52 ) 53 54 func RegisterAuthenticatorCreator(name string, creator Creator) { 55 authCreators[name] = creator 56 } 57 58 func NewAuthenticator(ctx context.Context, name string) (Authenticator, error) { 59 // allocate a unique authenticator for each context 60 createdAuthLock.Lock() // avoid concurrent map read/write 61 defer createdAuthLock.Unlock() 62 if auth, found := createdAuth[ctx]; found { 63 log.Debug("authenticator has been created:", name) 64 return auth, nil 65 } 66 creator, found := authCreators[strings.ToUpper(name)] 67 if !found { 68 return nil, common.NewError("auth driver name " + name + " not found") 69 } 70 auth, err := creator(ctx) 71 if err != nil { 72 return nil, err 73 } 74 createdAuth[ctx] = auth 75 return auth, err 76 }