chiark / gitweb /
transform: Discard previously-received packets
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 27 Sep 2014 23:40:04 +0000 (00:40 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 29 Sep 2014 15:30:52 +0000 (16:30 +0100)
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 <ijackson@chiark.greenend.org.uk>
transform-common.h

index f3405fbe9695653bc3e9367aded74b14a0b998c7..71596cb971a34a33eecde51e848996684a3840ea 100644 (file)
        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 {                                        \
            *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                                \
        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*/