From 73505dae67838a8024167a04066feefc05a4ed92 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 28 Sep 2014 00:40:04 +0100 Subject: [PATCH] transform: Discard previously-received packets Keep a bitmap of previously-received packets (by sequence number offset) and discard duplicates. This feature can only be enabled if the bitmap (32 bits) is big enough for the sequence number window (`max-skew'), but this is true by default, and the feature is enabled by default when available. Signed-off-by: Ian Jackson --- transform-common.h | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/transform-common.h b/transform-common.h index f3405fb..71596cb 100644 --- a/transform-common.h +++ b/transform-common.h @@ -16,6 +16,11 @@ if (skew<0x8fffffff) { \ /* Ok */ \ ti->lastrecvseq=seqnum; \ + if (skew < 32) \ + ti->recvbitmap <<= skew; \ + else \ + ti->recvbitmap=0; \ + skew=0; \ } else if ((0-skew)<(p)->max_seq_skew) { \ /* Ok */ \ } else { \ @@ -23,16 +28,26 @@ *errmsg="seqnum: too much skew"; \ return 2; \ } \ + if ((p)->dedupe) { \ + uint32_t recvbit=(uint32_t)1 << skew; \ + if (ti->recvbitmap & recvbit) { \ + *errmsg="seqnum: duplicate"; \ + return 2; \ + } \ + ti->recvbitmap |= recvbit; \ + } \ }while(0) #define SEQNUM_KEYED_FIELDS \ uint32_t sendseq; \ uint32_t lastrecvseq; \ + uint32_t recvbitmap; /* 1<<0 is lastrecvseq (i.e., most recent) */ \ bool_t keyed #define SEQNUM_KEYED_INIT(initlastrecvseq,initsendseq) \ (ti->lastrecvseq=(initlastrecvseq), \ ti->sendseq=(initsendseq), \ + ti->recvbitmap=0, \ ti->keyed=True) #define TRANSFORM_VALID \ @@ -74,11 +89,18 @@ ti->keyed=False; #define SEQNUM_PARAMS_FIELDS \ - uint32_t max_seq_skew + uint32_t max_seq_skew; \ + bool_t dedupe; #define SEQNUM_PARAMS_INIT(dict,p,desc,loc) \ (p)->max_seq_skew=dict_read_number((dict), "max-sequence-skew", \ - False, (desc), (loc), 10); - + False, (desc), (loc), 10); \ + bool_t can_dedupe=(p)->max_seq_skew < 32; \ + (p)->dedupe=dict_read_bool((dict), "dedupe", \ + False,(desc),(loc), can_dedupe); \ + if ((p)->dedupe && !can_dedupe) \ + cfgfatal(loc,"transform", \ + "cannot dedupe with max-sequence-skew>=32"); \ + else (void)0 #endif /*TRANSFORM_COMMON_H*/ -- 2.30.2