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:
parent
e691cd568a
commit
a1849f41cd
56
reliable.c
56
reliable.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user