]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
* gssapiP_generic.h: Include k5-platform.h.
authorKen Raeburn <raeburn@mit.edu>
Wed, 29 Oct 2003 00:30:00 +0000 (00:30 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 29 Oct 2003 00:30:00 +0000 (00:30 +0000)
(gssint_uint64): New typedef.
(g_order_init, g_order_check): Update decls.
* util_ordering.c (struct _queue): Change sequence number fields to
gssint_uint64.  Add mask field.
(queue_insert): Change sequence number to gssint_uint64.
(g_order_init): Change sequence numbers to gssint_uint64.  Add "wide_nums"
argument; initialize the queue mask field based on it.  Store a -1 as the first
element.
(g_order_check): Store and check elements as offsets from firstnum.  Mask to 32
bits if desired.

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/raeburn-gssapi-cfx@15845 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/gssapi/generic/ChangeLog
src/lib/gssapi/generic/gssapiP_generic.h
src/lib/gssapi/generic/util_ordering.c

index 5444c99d653e5627dbe109776d941792a85be820..98de9c59edaa57eec046f65b0f149b58c6786d75 100644 (file)
@@ -1,3 +1,17 @@
+2003-10-28  Ken Raeburn  <raeburn@mit.edu>
+
+       * gssapiP_generic.h: Include k5-platform.h.
+       (gssint_uint64): New typedef.
+       (g_order_init, g_order_check): Update decls.
+       * util_ordering.c (struct _queue): Change sequence number fields
+       to gssint_uint64.  Add mask field.
+       (queue_insert): Change sequence number to gssint_uint64.
+       (g_order_init): Change sequence numbers to gssint_uint64.  Add
+       "wide_nums" argument; initialize the queue mask field based on
+       it.  Store a -1 as the first element.
+       (g_order_check): Store and check elements as offsets from
+       firstnum.  Mask to 32 bits if desired.
+
 2003-07-17  Ken Raeburn  <raeburn@mit.edu>
 
        * Makefile.in (LIBNAME) [##WIN16##]: Don't define.
index 102ba699e15959dfc0478c99c866e094447f2ced..602f01425cfd0ad7aa0f787f43273eba51fa3a09 100644 (file)
@@ -40,6 +40,9 @@
 #include "gssapi_err_generic.h"
 #include <errno.h>
 
+#include "k5-platform.h"
+typedef UINT64_TYPE gssint_uint64;
+
 /** helper macros **/
 
 #define g_OID_equal(o1,o2) \
@@ -171,10 +174,10 @@ OM_uint32 g_display_com_err_status (OM_uint32 *minor_status,
                                   OM_uint32 status_value,
                                   gss_buffer_t status_string);
 
-gss_int32 g_order_init (void **queue, OM_uint32 seqnum,
-                                 int do_replay, int do_sequence);
+gss_int32 g_order_init (void **queue, gssint_uint64 seqnum,
+                                 int do_replay, int do_sequence, int wide);
 
-gss_int32 g_order_check (void **queue, OM_uint32 seqnum);
+gss_int32 g_order_check (void **queue, gssint_uint64 seqnum);
 
 void g_order_free (void **queue);
 
index 21a8b0641fee8f4cd0807400cfc270c000fa06cc..fe2eaafc2e43c872429bc105dae3d8c2bc347816 100644 (file)
@@ -38,8 +38,14 @@ typedef struct _queue {
    int do_sequence;
    int start;
    int length;
-   unsigned int firstnum;
-   unsigned int elem[QUEUE_LENGTH];
+   gssint_uint64 firstnum;
+   /* Stored as deltas from firstnum.  This way, the high bit won't
+      overflow unless we've actually gone through 2**n messages, or
+      gotten something *way* out of sequence.  */
+   gssint_uint64 elem[QUEUE_LENGTH];
+   /* All ones for 64-bit sequence numbers; 32 ones for 32-bit
+      sequence numbers.  */
+   gssint_uint64 mask;
 } queue;
 
 /* rep invariant:
@@ -51,7 +57,7 @@ typedef struct _queue {
 #define QELEM(q,i) ((q)->elem[(i)%QSIZE(q)])
 
 static void
-queue_insert(queue *q, int after, unsigned int seqnum)
+queue_insert(queue *q, int after, gssint_uint64 seqnum)
 {
    /* insert.  this is not the fastest way, but it's easy, and it's
       optimized for insert at end, which is the common case */
@@ -80,10 +86,10 @@ queue_insert(queue *q, int after, unsigned int seqnum)
       q->length++;
    }
 }
-   
+
 gss_int32
-g_order_init(void **vqueue, OM_uint32 seqnum,
-            int do_replay, int do_sequence)
+g_order_init(void **vqueue, gssint_uint64 seqnum,
+            int do_replay, int do_sequence, int wide_nums)
 {
    queue *q;
 
@@ -92,38 +98,49 @@ g_order_init(void **vqueue, OM_uint32 seqnum,
 
    q->do_replay = do_replay;
    q->do_sequence = do_sequence;
+   q->mask = wide_nums ? ~(gssint_uint64)0 : 0xffffffffUL;
 
    q->start = 0;
    q->length = 1;
    q->firstnum = seqnum;
-   q->elem[q->start] = seqnum-1;
+   q->elem[q->start] = ((gssint_uint64)0 - 1) & q->mask;
 
    *vqueue = (void *) q;
    return(0);
 }
 
 gss_int32
-g_order_check(void **vqueue, OM_uint32 seqnum)
+g_order_check(void **vqueue, gssint_uint64 seqnum)
 {
    queue *q;
    int i;
-   
+   gssint_uint64 expected;
+
    q = (queue *) (*vqueue);
 
    if (!q->do_replay && !q->do_sequence)
       return(GSS_S_COMPLETE);
 
+   /* All checks are done relative to the initial sequence number, to
+      avoid (or at least put off) the pain of wrapping.  */
+   seqnum -= q->firstnum;
+   /* If we're only doing 32-bit values, adjust for that again.
+
+      Note that this will probably be the wrong thing to if we get
+      2**32 messages sent with 32-bit sequence numbers.  */
+   seqnum &= q->mask;
+
    /* rule 1: expected sequence number */
 
-   if (seqnum == QELEM(q,q->start+q->length-1)+1) { 
+   expected = (QELEM(q,q->start+q->length-1)+1) & q->mask;
+   if (seqnum == expected) { 
       queue_insert(q, q->start+q->length-1, seqnum);
       return(GSS_S_COMPLETE);
    }
 
    /* rule 2: > expected sequence number */
 
-   if ((seqnum > QELEM(q,q->start+q->length-1)+1) ||
-       (seqnum < q->firstnum)) {
+   if ((seqnum > expected)) {
       queue_insert(q, q->start+q->length-1, seqnum);
       if (q->do_replay && !q->do_sequence)
         return(GSS_S_COMPLETE);
@@ -134,7 +151,20 @@ g_order_check(void **vqueue, OM_uint32 seqnum)
    /* rule 3: seqnum < seqnum(first) */
 
    if ((seqnum < QELEM(q,q->start)) &&
-       (seqnum >= q->firstnum)) {
+       /* Is top bit of whatever width we're using set?
+
+         We used to check for greater than or equal to firstnum, but
+         (1) we've since switched to compute values relative to
+         firstnum, so the lowest we can have is 0, and (2) the effect
+         of the original scheme was highly dependent on whether
+         firstnum was close to either side of 0.  (Consider
+         firstnum==0xFFFFFFFE and we miss three packets; the next
+         packet is *new* but would look old.)
+
+          This check should give us 2**31 or 2**63 messages "new", and
+          just as many "old".  That's not quite right either.  */
+       (seqnum & (1 + (q->mask >> 1)))
+       ) {
       if (q->do_replay && !q->do_sequence)
         return(GSS_S_OLD_TOKEN);
       else