/**
 * @file srtp/replay.c  SRTP replay protection
 *
 * Copyright (C) 2010 Creytiv.com
 */
#include <re_types.h>
#include <re_mbuf.h>
#include <re_list.h>
#include <re_aes.h>
#include <re_srtp.h>
#include "srtp.h"


enum {
	SRTP_WINDOW_SIZE = 64
};


void srtp_replay_init(struct replay *replay)
{
	if (!replay)
		return;

	replay->bitmap = 0;
	replay->lix    = 0;
}


/*
 * Returns false if packet disallowed, true if packet permitted
 */
bool srtp_replay_check(struct replay *replay, uint64_t ix)
{
	uint64_t diff;

	if (!replay)
		return false;

	if (ix > replay->lix) {
		diff = ix - replay->lix;

		if (diff < SRTP_WINDOW_SIZE) {   /* In window */
			replay->bitmap <<= diff;
			replay->bitmap |= 1;     /* set bit for this packet */
		}
		else
			replay->bitmap = 1;

		replay->lix = ix;
		return true;
	}

	diff = replay->lix - ix;
	if (diff >= SRTP_WINDOW_SIZE)
		return false;

	if (replay->bitmap & (1ULL << diff))
		return false; /* already seen */

	/* mark as seen */
	replay->bitmap |= (1ULL << diff);

	return true;
}
