- if (((index - s->rtcp_index) & 0x7fffffff) < 0x40000000)
- s->rtcp_index = index; /* Update index */
+ if (((index >> 31) != 0) != ((s->flags & SRTCP_UNENCRYPTED) == 0))
+ return EINVAL; // E-bit mismatch
+
+ index &= ~(1 << 31); // clear E-bit for counter
+
+ /* Updates SRTCP index (safe here) */
+ int32_t diff = index - s->rtcp_index;
+ if (diff > 0)
+ {
+ /* Packet in the future, good */
+ s->rtcp.window = s->rtcp.window << diff;
+ s->rtcp.window |= 1;
+ s->rtcp_index = index;
+ }
+ else
+ {
+ /* Packet in the past/present, bad */
+ diff = -diff;
+ if ((diff >= 64) || ((s->rtcp.window >> diff) & 1))
+ return EACCES; // replay attack!
+ s->rtp.window |= 1 << diff;
+ }