Change internal id of packet id to uint64

This allows to get rid of multiple casts and also prepares for the
larger packet id used by epoch data format.

Change-Id: If470af2eb456b2b10f9f2806933e026842188c42
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20241225142131.12543-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg30199.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Arne Schwabe 2024-12-25 15:21:31 +01:00 committed by Gert Doering
parent 82fd89a04f
commit 5aa7ce4eff
3 changed files with 55 additions and 59 deletions

View File

@ -36,6 +36,8 @@
#include "syshead.h" #include "syshead.h"
#include <stddef.h>
#include "packet_id.h" #include "packet_id.h"
#include "misc.h" #include "misc.h"
#include "integer.h" #include "integer.h"
@ -56,7 +58,7 @@ static void packet_id_debug_print(int msglevel,
const struct packet_id_rec *p, const struct packet_id_rec *p,
const struct packet_id_net *pin, const struct packet_id_net *pin,
const char *message, const char *message,
int value); packet_id_print_type value);
#endif /* ENABLE_DEBUG */ #endif /* ENABLE_DEBUG */
@ -65,7 +67,7 @@ packet_id_debug(int msglevel,
const struct packet_id_rec *p, const struct packet_id_rec *p,
const struct packet_id_net *pin, const struct packet_id_net *pin,
const char *message, const char *message,
int value) uint64_t value)
{ {
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG
if (unlikely(check_debug_level(msglevel))) if (unlikely(check_debug_level(msglevel)))
@ -115,22 +117,21 @@ packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
const time_t local_now = now; const time_t local_now = now;
if (p->seq_list) if (p->seq_list)
{ {
packet_id_type diff; int64_t diff;
/* /*
* If time value increases, start a new * If time value increases, start a new sequence number sequence.
* sequence number sequence.
*/ */
if (!CIRC_LIST_SIZE(p->seq_list) if (!CIRC_LIST_SIZE(p->seq_list)
|| pin->time > p->time || pin->time > p->time
|| (pin->id >= (packet_id_type)p->seq_backtrack || (pin->id >= p->seq_backtrack
&& pin->id - (packet_id_type)p->seq_backtrack > p->id)) && pin->id - p->seq_backtrack > p->id))
{ {
p->time = pin->time; p->time = pin->time;
p->id = 0; p->id = 0;
if (pin->id > (packet_id_type)p->seq_backtrack) if (pin->id > p->seq_backtrack)
{ {
p->id = pin->id - (packet_id_type)p->seq_backtrack; p->id = pin->id - p->seq_backtrack;
} }
CIRC_LIST_RESET(p->seq_list); CIRC_LIST_RESET(p->seq_list);
} }
@ -146,7 +147,7 @@ packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
} }
diff = p->id - pin->id; diff = p->id - pin->id;
if (diff < (packet_id_type) CIRC_LIST_SIZE(p->seq_list) if (diff < CIRC_LIST_SIZE(p->seq_list)
&& local_now > SEQ_EXPIRED) && local_now > SEQ_EXPIRED)
{ {
CIRC_LIST_ITEM(p->seq_list, diff) = local_now; CIRC_LIST_ITEM(p->seq_list, diff) = local_now;
@ -170,9 +171,8 @@ packet_id_reap(struct packet_id_rec *p)
const time_t local_now = now; const time_t local_now = now;
if (p->time_backtrack) if (p->time_backtrack)
{ {
int i;
bool expire = false; bool expire = false;
for (i = 0; i < CIRC_LIST_SIZE(p->seq_list); ++i) for (int i = 0; i < CIRC_LIST_SIZE(p->seq_list); ++i)
{ {
const time_t t = CIRC_LIST_ITEM(p->seq_list, i); const time_t t = CIRC_LIST_ITEM(p->seq_list, i);
if (t == SEQ_EXPIRED) if (t == SEQ_EXPIRED)
@ -200,7 +200,7 @@ bool
packet_id_test(struct packet_id_rec *p, packet_id_test(struct packet_id_rec *p,
const struct packet_id_net *pin) const struct packet_id_net *pin)
{ {
packet_id_type diff; uint64_t diff;
packet_id_debug(D_PID_DEBUG, p, pin, "PID_TEST", 0); packet_id_debug(D_PID_DEBUG, p, pin, "PID_TEST", 0);
@ -231,9 +231,9 @@ packet_id_test(struct packet_id_rec *p,
diff = p->id - pin->id; diff = p->id - pin->id;
/* keep track of maximum backtrack seen for debugging purposes */ /* keep track of maximum backtrack seen for debugging purposes */
if ((int)diff > p->max_backtrack_stat) if (diff > p->max_backtrack_stat)
{ {
p->max_backtrack_stat = (int)diff; p->max_backtrack_stat = diff;
packet_id_debug(D_PID_DEBUG_LOW, p, pin, "PID_ERR replay-window backtrack occurred", p->max_backtrack_stat); packet_id_debug(D_PID_DEBUG_LOW, p, pin, "PID_ERR replay-window backtrack occurred", p->max_backtrack_stat);
} }
@ -557,7 +557,7 @@ packet_id_debug_print(int msglevel,
const struct packet_id_rec *p, const struct packet_id_rec *p,
const struct packet_id_net *pin, const struct packet_id_net *pin,
const char *message, const char *message,
int value) packet_id_print_type value)
{ {
struct gc_arena gc = gc_new(); struct gc_arena gc = gc_new();
struct buffer out = alloc_buf_gc(256, &gc); struct buffer out = alloc_buf_gc(256, &gc);
@ -569,7 +569,7 @@ packet_id_debug_print(int msglevel,
CLEAR(tv); CLEAR(tv);
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
buf_printf(&out, "%s [%d]", message, value); buf_printf(&out, "%s [" packet_id_format "]", message, value);
buf_printf(&out, " [%s-%d] [", p->name, p->unit); buf_printf(&out, " [%s-%d] [", p->name, p->unit);
for (i = 0; sl != NULL && i < sl->x_size; ++i) for (i = 0; sl != NULL && i < sl->x_size; ++i)
{ {
@ -604,17 +604,17 @@ packet_id_debug_print(int msglevel,
} }
buf_printf(&out, "%c", c); buf_printf(&out, "%c", c);
} }
buf_printf(&out, "] %" PRIi64 ":" packet_id_format, (int64_t)p->time, (packet_id_print_type)p->id); buf_printf(&out, "] %" PRIi64 ":" packet_id_format, (int64_t)p->time, p->id);
if (pin) if (pin)
{ {
buf_printf(&out, " %" PRIi64 ":" packet_id_format, (int64_t)pin->time, (packet_id_print_type)pin->id); buf_printf(&out, " %" PRIi64 ":" packet_id_format, (int64_t)pin->time, pin->id);
} }
buf_printf(&out, " t=%" PRIi64 "[%d]", buf_printf(&out, " t=%" PRIi64 "[%d]",
(int64_t)prev_now, (int64_t)prev_now,
(int)(prev_now - tv.tv_sec)); (int)(prev_now - tv.tv_sec));
buf_printf(&out, " r=[%d,%d,%d,%d,%d]", buf_printf(&out, " r=[%d,%" PRIu64 ",%d,%" PRIu64 ",%d]",
(int)(p->last_reap - tv.tv_sec), (int)(p->last_reap - tv.tv_sec),
p->seq_backtrack, p->seq_backtrack,
p->time_backtrack, p->time_backtrack,

View File

@ -35,11 +35,13 @@
#include "error.h" #include "error.h"
#include "otime.h" #include "otime.h"
#if 1
/* /*
* These are the types that members of * These are the types that members of a struct packet_id_net are converted
* a struct packet_id_net are converted * to for network transmission and for saving to a persistent file.
* to for network transmission. *
* Note: data epoch data uses a 64 bit packet ID
* compromised of 16 bit epoch and 48 bit per-epoch packet counter.
* These are ephemeral and are never saved to a file.
*/ */
typedef uint32_t packet_id_type; typedef uint32_t packet_id_type;
#define PACKET_ID_MAX UINT32_MAX #define PACKET_ID_MAX UINT32_MAX
@ -64,31 +66,12 @@ typedef uint32_t net_time_t;
/* convert a net_time_t in network order to a time_t in host order */ /* convert a net_time_t in network order to a time_t in host order */
#define ntohtime(x) ((time_t)ntohl(x)) #define ntohtime(x) ((time_t)ntohl(x))
#else /* if 1 */
/*
* DEBUGGING ONLY.
* Make packet_id_type and net_time_t small
* to test wraparound logic and corner cases.
*/
typedef uint8_t packet_id_type;
typedef uint16_t net_time_t;
#define PACKET_ID_WRAP_TRIGGER 0x80
#define htonpid(x) (x)
#define ntohpid(x) (x)
#define htontime(x) htons((net_time_t)x)
#define ntohtime(x) ((time_t)ntohs(x))
#endif /* if 1 */
/* /*
* Printf formats for special types * Printf formats for special types
*/ */
#define packet_id_format "%u" #define packet_id_format "%" PRIu64
typedef unsigned int packet_id_print_type; typedef uint64_t packet_id_print_type;
/* /*
* Maximum allowed backtrack in * Maximum allowed backtrack in
@ -128,10 +111,10 @@ struct packet_id_rec
{ {
time_t last_reap; /* last call of packet_id_reap */ time_t last_reap; /* last call of packet_id_reap */
time_t time; /* highest time stamp received */ time_t time; /* highest time stamp received */
packet_id_type id; /* highest sequence number received */ uint64_t id; /* highest sequence number received */
int seq_backtrack; /* set from --replay-window */ uint64_t seq_backtrack; /* set from --replay-window */
int time_backtrack; /* set from --replay-window */ int time_backtrack; /* set from --replay-window */
int max_backtrack_stat; /* maximum backtrack seen so far */ uint64_t max_backtrack_stat; /* maximum backtrack seen so far */
bool initialized; /* true if packet_id_init was called */ bool initialized; /* true if packet_id_init was called */
struct seq_list *seq_list; /* packet-id "memory" */ struct seq_list *seq_list; /* packet-id "memory" */
const char *name; const char *name;
@ -164,7 +147,7 @@ struct packet_id_persist_file_image
*/ */
struct packet_id_send struct packet_id_send
{ {
packet_id_type id; uint64_t id;
time_t time; time_t time;
}; };
@ -174,8 +157,12 @@ struct packet_id_send
* sequence number. A long packet-id * sequence number. A long packet-id
* includes a timestamp as well. * includes a timestamp as well.
* *
* An epoch packet-id is a 16 bit epoch
* counter plus a 48 per-epoch packet-id
*
* Long packet-ids are used as IVs for * Long packet-ids are used as IVs for
* CFB/OFB ciphers. * CFB/OFB ciphers and for control channel
* messages.
* *
* This data structure is always sent * This data structure is always sent
* over the net in network byte order, * over the net in network byte order,
@ -191,9 +178,16 @@ struct packet_id_send
* 64 bit platforms use a * 64 bit platforms use a
* 64 bit time_t. * 64 bit time_t.
*/ */
/**
* Data structure for describing the packet id that is received/send to the
* network. This struct does not match the on wire format.
*/
struct packet_id_net struct packet_id_net
{ {
packet_id_type id; /* converted to packet_id_type on non-epoch data ids, does not contain
* the epoch but is a flat id */
uint64_t id;
time_t time; /* converted to net_time_t before transmission */ time_t time; /* converted to net_time_t before transmission */
}; };

View File

@ -90,8 +90,8 @@ test_packet_id_write_long(void **state)
now = 5010; now = 5010;
assert_true(packet_id_write(&data->pis, &data->test_buf, true, false)); assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
assert(data->pis.id == 1); assert_int_equal(data->pis.id, 1);
assert(data->pis.time == now); assert_int_equal(data->pis.time, now);
assert_true(data->test_buf_data.buf_id == htonl(1)); assert_true(data->test_buf_data.buf_id == htonl(1));
assert_true(data->test_buf_data.buf_time == htonl((uint32_t)now)); assert_true(data->test_buf_data.buf_time == htonl((uint32_t)now));
} }
@ -117,8 +117,8 @@ test_packet_id_write_long_prepend(void **state)
data->test_buf.offset = sizeof(data->test_buf_data); data->test_buf.offset = sizeof(data->test_buf_data);
now = 5010; now = 5010;
assert_true(packet_id_write(&data->pis, &data->test_buf, true, true)); assert_true(packet_id_write(&data->pis, &data->test_buf, true, true));
assert(data->pis.id == 1); assert_int_equal(data->pis.id, 1);
assert(data->pis.time == now); assert_int_equal(data->pis.time, now);
assert_true(data->test_buf_data.buf_id == htonl(1)); assert_true(data->test_buf_data.buf_id == htonl(1));
assert_true(data->test_buf_data.buf_time == htonl((uint32_t)now)); assert_true(data->test_buf_data.buf_time == htonl((uint32_t)now));
} }
@ -128,7 +128,8 @@ test_packet_id_write_short_wrap(void **state)
{ {
struct test_packet_id_write_data *data = *state; struct test_packet_id_write_data *data = *state;
data->pis.id = ~0; /* maximum 32-bit packet id */
data->pis.id = (packet_id_type)(~0);
assert_false(packet_id_write(&data->pis, &data->test_buf, false, false)); assert_false(packet_id_write(&data->pis, &data->test_buf, false, false));
} }
@ -137,7 +138,8 @@ test_packet_id_write_long_wrap(void **state)
{ {
struct test_packet_id_write_data *data = *state; struct test_packet_id_write_data *data = *state;
data->pis.id = ~0; /* maximum 32-bit packet id */
data->pis.id = (packet_id_type)(~0);
data->pis.time = 5006; data->pis.time = 5006;
/* Write fails if time did not change */ /* Write fails if time did not change */
@ -148,8 +150,8 @@ test_packet_id_write_long_wrap(void **state)
now = 5010; now = 5010;
assert_true(packet_id_write(&data->pis, &data->test_buf, true, false)); assert_true(packet_id_write(&data->pis, &data->test_buf, true, false));
assert(data->pis.id == 1); assert_int_equal(data->pis.id, 1);
assert(data->pis.time == now); assert_int_equal(data->pis.time, now);
assert_true(data->test_buf_data.buf_id == htonl(1)); assert_true(data->test_buf_data.buf_id == htonl(1));
assert_true(data->test_buf_data.buf_time == htonl((uint32_t)now)); assert_true(data->test_buf_data.buf_time == htonl((uint32_t)now));
} }