]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Support wraparound of reliable.[ch] packet IDs. In
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Thu, 17 Jul 2008 18:56:09 +0000 (18:56 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Thu, 17 Jul 2008 18:56:09 +0000 (18:56 +0000)
practice, wraparound of the packet ID sequence is
extremely unlikely since the sequence is restarted
for each mid-session TLS renegotiation.  But we will
support it for completeness.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3065 e7ae566f-a301-0410-adde-c780ea21d3b5

reliable.c

index 743a008f4e0314c57a157dbc76f9fe4bf75d5cdc..4958f7ead7ef6f716d431743078bccc4728c593f 100644 (file)
 
 #include "memdbg.h"
 
+/*
+ * verify that test - base < extent while allowing for base or test wraparound
+ */
+static inline bool
+reliable_pid_in_range (const packet_id_type test,
+                      const packet_id_type base,
+                      const unsigned int extent)
+{
+  if (test >= base)
+    {
+      if (test - base < extent)
+       return true;
+    }
+  else
+    {      
+      const packet_id_type be = base + extent;
+      if (test < be && be < base)
+       return true;
+    }
+
+  return false;
+}
+
+/*
+ * verify that p1 < p2  while allowing for p1 or p2 wraparound
+ */
+static inline bool
+reliable_pid_min (const packet_id_type p1,
+                 const packet_id_type p2)
+{
+  return !reliable_pid_in_range (p1, p2, 0x80000000);
+}
+
 /* check if a particular packet_id is present in ack */
 static inline bool
 reliable_ack_packet_id_present (struct reliable_ack *ack, packet_id_type pid)
@@ -330,7 +363,7 @@ reliable_not_replay (const struct reliable *rel, packet_id_type id)
 {
   struct gc_arena gc = gc_new ();
   int i;
-  if (id < rel->packet_id)
+  if (reliable_pid_min (id, rel->packet_id))
     goto bad;
   for (i = 0; i < rel->size; ++i)
     {
@@ -352,18 +385,17 @@ bool
 reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id)
 {
   struct gc_arena gc = gc_new ();
-  int ret;
 
-  if ((int)id < (int)rel->packet_id + rel->size)
-    {
-      ret = true;
-    }
-  else
+  const int ret = reliable_pid_in_range (id, rel->packet_id, rel->size);
+
+  if (!ret)
     {
       dmsg (D_REL_LOW, "ACK " packet_id_format " breaks sequentiality: %s",
           (packet_id_print_type)id, reliable_print_ids (rel, &gc));
-      ret = false;
     }
+
+  dmsg (D_REL_DEBUG, "ACK RWBS rel->size=%d rel->packet_id=%08x id=%08x ret=%d\n", rel->size, rel->packet_id, id, ret);
+
   gc_free (&gc);
   return ret;
 }
@@ -401,7 +433,7 @@ reliable_get_buf_output_sequenced (struct reliable *rel)
       const struct reliable_entry *e = &rel->array[i];
       if (e->active)
        {
-         if (!min_id_defined || e->packet_id < min_id)
+         if (!min_id_defined || reliable_pid_min (e->packet_id, min_id))
            {
              min_id_defined = true;
              min_id = e->packet_id;
@@ -409,7 +441,7 @@ reliable_get_buf_output_sequenced (struct reliable *rel)
        }
     }
 
-  if (!min_id_defined || (int)(rel->packet_id - min_id) < rel->size)
+  if (!min_id_defined || reliable_pid_in_range (rel->packet_id, min_id, rel->size))
     {
       ret = reliable_get_buf (rel);
     }
@@ -496,7 +528,7 @@ reliable_send (struct reliable *rel, int *opcode)
       struct reliable_entry *e = &rel->array[i];
       if (e->active && local_now >= e->next_try)
        {
-         if (!best || e->packet_id < best->packet_id)
+         if (!best || reliable_pid_min (e->packet_id, best->packet_id))
            best = e;
        }
     }
@@ -592,7 +624,7 @@ reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf,
          e->packet_id = pid;
 
          /* check for replay */
-         ASSERT (pid >= rel->packet_id);
+         ASSERT (!reliable_pid_min (pid, rel->packet_id));
 
          e->opcode = opcode;
          e->next_try = 0;