mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-07 10:27:43 +00:00
PacketHistory debloat RAM allocations (#7034)
* PacketHistory debloat RAM allocations * Removed FLOOD_EXPIRE_TIME option. We have static buffer now. * Remove mx_ prefix from recentPackets * Remember no less than 100 packet not to make reflood hell * Cleanup * PacketHistory max no less than 100 * no less than 100 means max of 100 or a given value of course. * Care to not do duplicate entries. Cleanups. --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
@@ -1,49 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "NodeDB.h"
|
||||
#include <unordered_set>
|
||||
|
||||
/// We clear our old flood record 10 minutes after we see the last of it
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
#define FLOOD_EXPIRE_TIME (5 * 1000L) // Don't allow too many packets to accumulate when fuzzing.
|
||||
#else
|
||||
#define FLOOD_EXPIRE_TIME (10 * 60 * 1000L)
|
||||
#endif
|
||||
|
||||
#define NUM_RELAYERS \
|
||||
3 // Number of relayer we keep track of. Use 3 to be efficient with memory alignment of PacketRecord to 16 bytes
|
||||
|
||||
/**
|
||||
* A record of a recent message broadcast
|
||||
*/
|
||||
struct PacketRecord {
|
||||
NodeNum sender;
|
||||
PacketId id;
|
||||
uint32_t rxTimeMsec; // Unix time in msecs - the time we received it
|
||||
uint8_t next_hop; // The next hop asked for this packet
|
||||
uint8_t relayed_by[NUM_RELAYERS]; // Array of nodes that relayed this packet
|
||||
|
||||
bool operator==(const PacketRecord &p) const { return sender == p.sender && id == p.id; }
|
||||
};
|
||||
|
||||
class PacketRecordHashFunction
|
||||
{
|
||||
public:
|
||||
size_t operator()(const PacketRecord &p) const { return (std::hash<NodeNum>()(p.sender)) ^ (std::hash<PacketId>()(p.id)); }
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a mixin that adds a record of past packets we have seen
|
||||
*/
|
||||
class PacketHistory
|
||||
{
|
||||
private:
|
||||
std::unordered_set<PacketRecord, PacketRecordHashFunction> recentPackets;
|
||||
struct PacketRecord { // A record of a recent message broadcast, no need to be visible outside this class.
|
||||
NodeNum sender;
|
||||
PacketId id;
|
||||
uint32_t rxTimeMsec; // Unix time in msecs - the time we received it, 0 means empty
|
||||
uint8_t next_hop; // The next hop asked for this packet
|
||||
uint8_t relayed_by[NUM_RELAYERS]; // Array of nodes that relayed this packet
|
||||
}; // 4B + 4B + 4B + 1B + 3B = 16B
|
||||
|
||||
void clearExpiredRecentPackets(); // clear all recentPackets older than FLOOD_EXPIRE_TIME
|
||||
uint32_t recentPacketsCapacity =
|
||||
0; // Can be set in constructor, no need to recompile. Used to allocate memory for mx_recentPackets.
|
||||
PacketRecord *recentPackets = NULL; // Simple and fixed in size. Debloat.
|
||||
|
||||
/** Find a packet record in history.
|
||||
* @param sender NodeNum
|
||||
* @param id PacketId
|
||||
* @return pointer to PacketRecord if found, NULL if not found */
|
||||
PacketRecord *find(NodeNum sender, PacketId id);
|
||||
|
||||
/** Insert/Replace oldest PacketRecord in mx_recentPackets.
|
||||
* @param r PacketRecord to insert or replace */
|
||||
void insert(PacketRecord &r); // Insert or replace a packet record in the history
|
||||
|
||||
/* Check if a certain node was a relayer of a packet in the history given iterator
|
||||
* @return true if node was indeed a relayer, false if not */
|
||||
bool wasRelayer(const uint8_t relayer, PacketRecord &r);
|
||||
|
||||
PacketHistory(const PacketHistory &); // non construction-copyable
|
||||
PacketHistory &operator=(const PacketHistory &); // non copyable
|
||||
public:
|
||||
PacketHistory();
|
||||
explicit PacketHistory(uint32_t size = -1); // Constructor with size parameter, default is PACKETHISTORY_MAX
|
||||
~PacketHistory();
|
||||
|
||||
/**
|
||||
* Update recentBroadcasts and return true if we have already seen this packet
|
||||
@@ -59,10 +57,9 @@ class PacketHistory
|
||||
* @return true if node was indeed a relayer, false if not */
|
||||
bool wasRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
|
||||
|
||||
/* Check if a certain node was a relayer of a packet in the history given iterator
|
||||
* @return true if node was indeed a relayer, false if not */
|
||||
bool wasRelayer(const uint8_t relayer, std::unordered_set<PacketRecord, PacketRecordHashFunction>::iterator r);
|
||||
|
||||
// Remove a relayer from the list of relayers of a packet in the history given an ID and sender
|
||||
void removeRelayer(const uint8_t relayer, const uint32_t id, const NodeNum sender);
|
||||
};
|
||||
|
||||
// To check if the PacketHistory was initialized correctly by constructor
|
||||
bool initOk(void) { return recentPackets != NULL && recentPacketsCapacity != 0; }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user