0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 03:52:28 +02:00

Support wraparound of reliable.[ch] packet IDs. In

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
This commit is contained in:
james 2008-07-17 18:56:09 +00:00
parent e691cd568a
commit a1849f41cd

View File

@ -38,6 +38,39 @@
#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;