chiark / gitweb /
admin, resolve ops bugfix: initialize tag in resop early.
[tripe] / servutil.c
index 590327db4ad36aa368133c90bda98fb40fe82060..92a5f775f03b456a0068317508db70294bedcb77 100644 (file)
@@ -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 -------------------------------------------------*/