mirror of https://github.com/XTLS/Xray-core
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
1.5 KiB
80 lines
1.5 KiB
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 |
|
}
|
|
|