X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/b4e566689f469cc1cffe99e50e16a346d0f9832d..452bf3f6897b8c6a22b51e1ef228da39136d51a7:/servutil.c?ds=sidebyside diff --git a/servutil.c b/servutil.c index 590327db..92a5f775 100644 --- a/servutil.c +++ b/servutil.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: servutil.c,v 1.5 2004/04/08 01:36:17 mdw Exp $ + * $Id$ * * Various handy server-only utilities * @@ -91,4 +91,53 @@ const char *timestr(time_t t) return ((const char *)buf_t); } +/* --- @seq_reset@ --- * + * + * Arguments: @seqwin *s@ = sequence-checking window + * + * Returns: --- + * + * Use: Resets a sequence number window. + */ + +void seq_reset(seqwin *s) { s->seq = 0; s->win = 0; } + +/* --- @seq_check@ --- * + * + * Arguments: @seqwin *s@ = sequence-checking window + * @uint32 q@ = sequence number to check + * @const char *service@ = service to report message from + * + * Returns: Zero on success, nonzero if the sequence number was bad. + * + * Use: Checks a sequence number against the window, updating things + * as necessary. + */ + +int seq_check(seqwin *s, uint32 q, const char *service) +{ + uint32 qbit; + uint32 n; + + if (q < s->seq) { + a_warn(service, "replay", "old-sequence", A_END); + return (-1); + } + if (q >= s->seq + SEQ_WINSZ) { + n = q - (s->seq + SEQ_WINSZ - 1); + if (n < SEQ_WINSZ) + s->win >>= n; + else + s->win = 0; + s->seq += n; + } + qbit = 1 << (q - s->seq); + if (s->win & qbit) { + a_warn(service, "replay", "duplicated-sequence", A_END); + return (-1); + } + s->win |= qbit; + return (0); +} + /*----- That's all, folks -------------------------------------------------*/