mirror of https://github.com/XTLS/Xray-core
81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
|
package stats
|
||
|
|
||
|
import (
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// OnlineMap is an implementation of stats.OnlineMap.
|
||
|
type OnlineMap struct {
|
||
|
value int
|
||
|
ipList map[string]time.Time
|
||
|
access sync.RWMutex
|
||
|
lastCleanup time.Time
|
||
|
cleanupPeriod time.Duration
|
||
|
}
|
||
|
|
||
|
// NewOnlineMap creates a new instance of OnlineMap.
|
||
|
func NewOnlineMap() *OnlineMap {
|
||
|
return &OnlineMap{
|
||
|
ipList: make(map[string]time.Time),
|
||
|
lastCleanup: time.Now(),
|
||
|
cleanupPeriod: 10 * time.Second,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Count implements stats.OnlineMap.
|
||
|
func (c *OnlineMap) Count() int {
|
||
|
return c.value
|
||
|
}
|
||
|
|
||
|
// List implements stats.OnlineMap.
|
||
|
func (c *OnlineMap) List() []string {
|
||
|
return c.GetKeys()
|
||
|
}
|
||
|
|
||
|
// AddIP implements stats.OnlineMap.
|
||
|
func (c *OnlineMap) AddIP(ip string) {
|
||
|
list := c.ipList
|
||
|
|
||
|
if ip == "127.0.0.1" {
|
||
|
return
|
||
|
}
|
||
|
if _, ok := list[ip]; !ok {
|
||
|
c.access.Lock()
|
||
|
list[ip] = time.Now()
|
||
|
c.access.Unlock()
|
||
|
}
|
||
|
if time.Since(c.lastCleanup) > c.cleanupPeriod {
|
||
|
list = c.RemoveExpiredIPs(list)
|
||
|
c.lastCleanup = time.Now()
|
||
|
}
|
||
|
|
||
|
c.value = len(list)
|
||
|
c.ipList = list
|
||
|
}
|
||
|
|
||
|
func (c *OnlineMap) GetKeys() []string {
|
||
|
c.access.RLock()
|
||
|
defer c.access.RUnlock()
|
||
|
|
||
|
keys := []string{}
|
||
|
for k := range c.ipList {
|
||
|
keys = append(keys, k)
|
||
|
}
|
||
|
return keys
|
||
|
}
|
||
|
|
||
|
func (c *OnlineMap) RemoveExpiredIPs(list map[string]time.Time) map[string]time.Time {
|
||
|
c.access.Lock()
|
||
|
defer c.access.Unlock()
|
||
|
|
||
|
now := time.Now()
|
||
|
for k, t := range list {
|
||
|
diff := now.Sub(t)
|
||
|
if diff.Seconds() > 20 {
|
||
|
delete(list, k)
|
||
|
}
|
||
|
}
|
||
|
return list
|
||
|
}
|