-#define SEQNUM_CHECK(seqnum, p) do{ \
- uint32_t skew=seqnum-ti->lastrecvseq; \
- if (skew<0x8fffffff) { \
- /* Ok */ \
- ti->lastrecvseq=seqnum; \
- } else if ((0-skew)<(p)->max_seq_skew) { \
- /* Ok */ \
- } else { \
- /* Too much skew */ \
- *errmsg="seqnum: too much skew"; \
- return 2; \
- } \
+#define RECVBITMAP_SIZE 32
+typedef uint32_t recvbitmap_type;
+
+#define SEQNUM_CHECK(seqnum, p) do{ \
+ uint32_t skew=seqnum-ti->lastrecvseq; \
+ if (skew<0x8fffffff) { \
+ /* Ok */ \
+ ti->lastrecvseq=seqnum; \
+ if (skew < RECVBITMAP_SIZE) \
+ ti->recvbitmap <<= skew; \
+ else \
+ ti->recvbitmap=0; \
+ skew=0; \
+ } else if ((0-skew)<(p)->max_seq_skew) { \
+ /* Ok */ \
+ } else { \
+ /* Too much skew */ \
+ *errmsg="seqnum: too much skew"; \
+ return transform_apply_seqrange; \
+ } \
+ if ((p)->dedupe) { \
+ recvbitmap_type recvbit=(uint32_t)1 << skew; \
+ if (ti->recvbitmap & recvbit) { \
+ *errmsg="seqnum: duplicate"; \
+ return transform_apply_seqdupe; \
+ } \
+ ti->recvbitmap |= recvbit; \
+ } \