/* Packet replay detection. * Allows ID backtrack of up to REPLAY_WINDOW_SIZE - 1.
*/ int ovpn_pktid_recv(struct ovpn_pktid_recv *pr, u32 pkt_id, u32 pkt_time)
{ constunsignedlong now = jiffies; int ret;
/* ID must not be zero */ if (unlikely(pkt_id == 0)) return -EINVAL;
spin_lock_bh(&pr->lock);
/* expire backtracks at or below pr->id after PKTID_RECV_EXPIRE time */ if (unlikely(time_after_eq(now, pr->expire)))
pr->id_floor = pr->id;
/* time changed? */ if (unlikely(pkt_time != pr->time)) { if (pkt_time > pr->time) { /* time moved forward, accept */
pr->base = 0;
pr->extent = 0;
pr->id = 0;
pr->time = pkt_time;
pr->id_floor = 0;
} else { /* time moved backward, reject */
ret = -ETIME; goto out;
}
}
if (likely(pkt_id == pr->id + 1)) { /* well-formed ID sequence (incremented by 1) */
pr->base = REPLAY_INDEX(pr->base, -1);
pr->history[pr->base / 8] |= (1 << (pr->base % 8)); if (pr->extent < REPLAY_WINDOW_SIZE)
++pr->extent;
pr->id = pkt_id;
} elseif (pkt_id > pr->id) { /* ID jumped forward by more than one */ constunsignedint delta = pkt_id - pr->id;
if (delta < REPLAY_WINDOW_SIZE) { unsignedint i;
pr->base = REPLAY_INDEX(pr->base, -delta);
pr->history[pr->base / 8] |= (1 << (pr->base % 8));
pr->extent += delta; if (pr->extent > REPLAY_WINDOW_SIZE)
pr->extent = REPLAY_WINDOW_SIZE; for (i = 1; i < delta; ++i) { unsignedint newb = REPLAY_INDEX(pr->base, i);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.