aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSmoke <[email protected]>2024-01-31 10:18:12 -1000
committerSmoke <[email protected]>2024-02-02 09:52:08 -1000
commit67c102385e5a4e3b29c29bbe95071eabd45b4fb9 (patch)
tree31d2ea00fd736eb1b3e41312da1cbef75fd837c3
parentffcb5db042e1f74b93020a9e840704eb9984913c (diff)
add packet deduplicator
-rw-r--r--dedupe.go66
1 files changed, 66 insertions, 0 deletions
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
+}