Why copies are normal in a mesh
Radio is a broadcast medium. When a device transmits, every neighbour in range hears it. In a mesh where neighbours relay for each other, that means a single message quickly exists in several places at once.
Take four devices, where A can hear B and C, and B and C can both hear D. A sends a message. B and C both receive it and both rebroadcast it. D now hears it twice, once from each. If D relays too, B and C hear it again from D. RFC 6621, the IETF’s Simplified Multicast Forwarding specification, lists the two causes in one sentence: packets may go back out over the same interface they arrived on, and routers “may also receive multiple copies of the same packets from different neighbors”.
None of this is a fault. Multiple paths are what make a mesh resilient. But if every copy were treated as new, each device would forward the same message again and again, and the network would fill with its own echoes. A hop limit stops this eventually; duplicate detection stops it at the first repeat.
Give each message a name
Duplicate detection starts with an identifier that stays the same on every copy. Mesh routing protocols commonly build it from two parts: who created the message and a counter that the creator increases for each new one.
- RFC 5444, the shared message format for IETF mesh routing protocols, says that when the originator address and message sequence number are both present, the header “provides for duplicate suppression”. Together with the message type, they identify the message until the sequence number wraps round and repeats.
- AODV (RFC 3561) identifies each route request by the originator’s address and an RREQ ID. A node that has seen the same pair recently silently discards the new copy.
- B.A.T.M.A.N. gives every originator message a sequence number set by its originator, so a node can tell whether it has received that message before.
An originator and sequence number can be checked from the header alone, without reading the message body. RFC 5444 lists this separation of forwarding from processing among the properties it was designed for.
RFC 6621 also describes a second approach, hash-based detection: the relay hashes the parts of the header that do not change in transit, together with the payload, and treats a matching hash as a duplicate. The RFC leaves the choice between the two to the deployment, but all routers in one network must use the same method.
Remember what you have seen
Each device then keeps a cache of recent identifiers and checks every arriving message against it.
- Bluetooth Mesh requires every node to implement a Network Message Cache of recently seen messages. A message found in the cache “is immediately discarded”.
- OLSR (RFC 3626) keeps a Duplicate Set. Each entry records the originator, the sequence number, whether the message has already been retransmitted, the interfaces it arrived on, and an expiry time.
- RFC 6621 recommends keeping a history of recently processed packets, held long enough to cover the longest time a packet can take to cross the network.
That last point is the sizing rule. If the cache forgets an identifier before the slowest copy arrives, the copy looks new and is forwarded again. In a mesh that holds messages while devices are out of range, a copy can arrive much later than on a live link, so the cache needs to last longer. The general trade-offs of windows and identifiers are covered in What is message deduplication?; in a mesh, every relay keeps such a cache, not only the recipient.
Processing once, forwarding once
A device can do two things with a message: act on it, and pass it on. Mesh protocols often track these separately, because the right answer can differ.
OLSRv2 (RFC 7181) keeps three records. A Received Set per interface notes what has arrived there, a Processed Set notes what the router has acted on, and a Forwarded Set notes what it has sent on. The RFC says together they ensure a message “is processed at most once and is forwarded at most once” per interface. Each record identifies a message by its type, originator address and sequence number. OLSRv2 also has a router silently discard any copy of a message it originated itself, which removes the echo of its own broadcasts coming back from neighbours.
Keeping the two apart lets a device act on a message without being one of the devices chosen to retransmit it. In OLSR, neighbours not selected as multipoint relays still receive and process broadcasts but do not retransmit them. B.A.T.M.A.N. goes further for its own announcements: a node rebroadcasts each one at most once, and only if it arrived from the neighbour it currently judges to be the best next hop towards the originator.
Fewer copies to begin with
A cache stops any one device forwarding twice, but in plain flooding every device still forwards once, and in a dense network many of those transmissions reach nobody new. Choosing a subset of relays and adding a small random delay before forwarding, so neighbours do not all transmit at the same instant, both reduce the number of copies in the air. What is flooding in a mesh network? covers those techniques. They work alongside duplicate detection, not instead of it: RFC 6621 still requires a cache even when every node forwards, and describes it as critical in that mode.
Duplicate detection can be attacked
Because a cache entry blocks later copies, a forged or tampered copy that arrives first can block the real one. RFC 6621 describes an attacker who lowers the hop limit on a copy and delivers it early, so the relay records the message as seen and then refuses the genuine copy. It suggests storing hop limit information with each cache entry. It also warns that sequence-based identifiers are predictable, and recommends mixing in an internal hash of the packet content.