From 67c102385e5a4e3b29c29bbe95071eabd45b4fb9 Mon Sep 17 00:00:00 2001 From: Smoke <86024507+crypto-smoke@users.noreply.github.com> Date: Wed, 31 Jan 2024 10:18:12 -1000 Subject: add packet deduplicator --- dedupe.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dedupe.go diff --git a/dedupe.go b/dedupe.go new file mode 100644 index 0000000..2b103b8 --- /dev/null +++ b/dedupe.go @@ -0,0 +1,66 @@ +package meshtastic + +import ( + "encoding/hex" + "fmt" + "hash" + "sync" + "time" +) + +type PacketDeduplicator struct { + hasher hash.Hash + expiresAfter time.Duration + sync.RWMutex + seen map[string]time.Time +} + +func NewDeduplicator(hasher hash.Hash, expiresAfter time.Duration) *PacketDeduplicator { + pd := PacketDeduplicator{ + seen: make(map[string]time.Time), + hasher: hasher, + expiresAfter: expiresAfter, + } + go func() { + for { + time.Sleep(expiresAfter) + pd.Lock() + for packet, timestamp := range pd.seen { + if time.Since(timestamp) > pd.expiresAfter { + delete(pd.seen, packet) + } + } + pd.Unlock() + } + }() + + return &pd +} +func (p *PacketDeduplicator) Seen(sender, packetID uint32) bool { + asString := fmt.Sprintf("%d-%d", sender, packetID) + p.RLock() + if _, exists := p.seen[asString]; !exists { + p.RUnlock() + p.Lock() + defer p.Unlock() + p.seen[asString] = time.Now() + return false + } + p.RUnlock() + return true +} +func (p *PacketDeduplicator) SeenData(data []byte) bool { + hashed := p.hasher.Sum(data) + asHex := hex.EncodeToString(hashed) + p.RLock() + if _, exists := p.seen[asHex]; !exists { + p.RUnlock() + p.Lock() + defer p.Unlock() + p.seen[asHex] = time.Now() + return false + } + p.RUnlock() + + return true +} -- cgit v1.2.3