From bb290ab7cbd6af7b38de87e89c0906f65ec2c631 Mon Sep 17 00:00:00 2001 From: Kevin Matz Date: Sat, 28 Aug 2021 12:23:20 -0400 Subject: [PATCH] validate incoming sequence number --- protocols/sacn/receiver.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/protocols/sacn/receiver.cpp b/protocols/sacn/receiver.cpp index c6430fa..93ef31a 100644 --- a/protocols/sacn/receiver.cpp +++ b/protocols/sacn/receiver.cpp @@ -26,6 +26,8 @@ #include "receiver.h" #include "config.h" +#include + namespace sACN { /** @@ -220,6 +222,29 @@ void Receiver::dataFrameHandler(ACN::PDU::Message frame) { if (source->sync_address != 0) subscribe(source->sync_address); + /// > \cite sACN 6.2.5 E1.31 Data Packet: Sequence Number + /// > In a routed network environment it is possible for packets to be + /// > received in a different order to the one in which they were sent. The + /// > sequence number allows receivers or diagnostic equipment to detect out + /// > of sequence or lost packets. + /// Assume that sources transmitting a sequence number of 0 do not support + /// sequencing. + if (source->sequence_number != 0 && universe->provenance()) + { + auto seq = source->sequence_number; + auto old = universe->provenance()->sequence_number; + auto hasWrapped = [seq, old] () { + auto threshold = std::numeric_limits::max() * 0.9; + if (seq < old && old > threshold) + return true; + return false; + }; + if (seq != old + 1) + ; // missed packet! + if (seq <= old && !hasWrapped()) + return; // out of sequence packet! + } + // PDU data will be a block of DMP auto block = static_cast*>(frame->data()); for (auto const &dmp : *block->pdu)