mirror of
https://github.com/andatoshiki/shikigrid.git
synced 2026-06-05 19:56:27 +00:00
123 lines
2.3 KiB
Go
123 lines
2.3 KiB
Go
package mesh
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/evilsocket/islazy/fs"
|
|
"github.com/evilsocket/islazy/log"
|
|
"math"
|
|
"os"
|
|
"path"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Memory struct {
|
|
sync.Mutex
|
|
path string
|
|
peers map[string]*Peer
|
|
}
|
|
|
|
func MemoryFromPath(path string) (err error, mem *Memory) {
|
|
if path, err = fs.Expand(path); err != nil {
|
|
return err, nil
|
|
}
|
|
|
|
mem = &Memory{
|
|
path: path,
|
|
peers: make(map[string]*Peer),
|
|
}
|
|
|
|
if !fs.Exists(path) {
|
|
log.Debug("creating %s ...", path)
|
|
if err = os.MkdirAll(path, os.ModePerm); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
err = fs.Glob(path, "*.json", func(fileName string) error {
|
|
log.Debug("loading %s ...", fileName)
|
|
data, err := os.ReadFile(fileName)
|
|
if err != nil {
|
|
log.Error("error loading %s: %v", fileName, err)
|
|
return nil
|
|
}
|
|
|
|
var peer jsonPeer
|
|
if err = json.Unmarshal(data, &peer); err != nil {
|
|
log.Error("error loading %s: %v", fileName, err)
|
|
return nil
|
|
}
|
|
|
|
mem.peers[peer.Fingerprint] = peerFromJSON(peer)
|
|
return nil
|
|
})
|
|
|
|
log.Debug("loaded %d known peers", len(mem.peers))
|
|
|
|
return
|
|
}
|
|
|
|
func (mem *Memory) Size() int {
|
|
mem.Lock()
|
|
defer mem.Unlock()
|
|
return len(mem.peers)
|
|
}
|
|
|
|
func (mem *Memory) Of(fingerprint string) *Peer {
|
|
mem.Lock()
|
|
defer mem.Unlock()
|
|
|
|
if peer, found := mem.peers[fingerprint]; found {
|
|
return peer
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (mem *Memory) List() []*Peer {
|
|
mem.Lock()
|
|
defer mem.Unlock()
|
|
|
|
list := make([]*Peer, 0)
|
|
for _, peer := range mem.peers {
|
|
list = append(list, peer)
|
|
}
|
|
|
|
return list
|
|
}
|
|
|
|
func (mem *Memory) Track(fingerprint string, peer *Peer) error {
|
|
mem.Lock()
|
|
defer mem.Unlock()
|
|
|
|
if encounter, found := mem.peers[fingerprint]; !found {
|
|
// peer first encounter
|
|
peer.Encounters = 1
|
|
peer.MetAt = time.Now()
|
|
peer.PrevSeenAt = peer.SeenAt
|
|
} else {
|
|
// we met this peer before
|
|
if encounter.Encounters < math.MaxUint64 {
|
|
encounter.Encounters++
|
|
}
|
|
peer.PrevSeenAt = encounter.SeenAt
|
|
peer.MetAt = encounter.MetAt
|
|
peer.Encounters = encounter.Encounters
|
|
}
|
|
|
|
peer.SeenAt = time.Now()
|
|
|
|
// save/update peer data in memory
|
|
mem.peers[fingerprint] = peer
|
|
// save/update peer data on disk
|
|
fileName := path.Join(mem.path, fmt.Sprintf("%s.json", fingerprint))
|
|
if data, err := json.Marshal(peer); err != nil {
|
|
return err
|
|
} else if err := os.WriteFile(fileName, data, os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|