Files
openlan/pkg/app/online.go
2024-03-27 15:46:48 +08:00

97 lines
2.0 KiB
Go
Executable File

package app
import (
"container/list"
"sync"
"time"
"github.com/luscis/openlan/pkg/cache"
"github.com/luscis/openlan/pkg/config"
"github.com/luscis/openlan/pkg/libol"
"github.com/luscis/openlan/pkg/models"
)
type Online struct {
lock sync.RWMutex
maxSize int
lineMap map[string]*models.Line
lineList *list.List
master Master
}
func NewOnline(m Master) *Online {
c := config.Get()
ms := c.Perf.OnLine
return &Online{
maxSize: ms,
lineMap: make(map[string]*models.Line, ms),
lineList: list.New(),
master: m,
}
}
func (o *Online) OnFrame(client libol.SocketClient, frame *libol.FrameMessage) error {
if frame.IsControl() {
return nil
}
if libol.HasLog(libol.LOG) {
libol.Log("Online.OnFrame %s.", frame)
}
proto, err := frame.Proto()
if err != nil {
libol.Warn("Online.OnFrame %s", err)
return err
}
if proto.Ip4 != nil {
ip := proto.Ip4
line := models.NewLine(libol.EthIp4)
line.IpSource = ip.Source
line.IpDest = ip.Destination
line.IpProtocol = ip.Protocol
if proto.Tcp != nil {
tcp := proto.Tcp
line.PortDest = tcp.Destination
line.PortSource = tcp.Source
} else if proto.Udp != nil {
udp := proto.Udp
line.PortDest = udp.Destination
line.PortSource = udp.Source
}
o.AddLine(line)
}
return nil
}
func (o *Online) popLine() {
if o.lineList.Len() < o.maxSize {
return
}
e := o.lineList.Front()
if e == nil {
return
}
if lastLine, ok := e.Value.(*models.Line); ok {
o.lineList.Remove(e)
cache.Online.Del(lastLine.String())
delete(o.lineMap, lastLine.String())
}
}
func (o *Online) AddLine(line *models.Line) {
o.lock.Lock()
defer o.lock.Unlock()
if libol.HasLog(libol.LOG) {
libol.Log("Online.AddLine %s and len %d", line, o.lineList.Len())
}
key := line.String()
if find, ok := o.lineMap[key]; !ok {
o.popLine()
o.lineList.PushBack(line)
o.lineMap[key] = line
cache.Online.Add(line)
} else if find != nil {
find.HitTime = time.Now().Unix()
cache.Online.Update(find)
}
}