summaryrefslogtreecommitdiff
path: root/src/openvpn/reliable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/reliable.c')
-rw-r--r--src/openvpn/reliable.c954
1 files changed, 502 insertions, 452 deletions
diff --git a/src/openvpn/reliable.c b/src/openvpn/reliable.c
index 22883a7..57cdd78 100644
--- a/src/openvpn/reliable.c
+++ b/src/openvpn/reliable.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -48,226 +48,256 @@
* verify that test - base < extent while allowing for base or test wraparound
*/
static inline bool
-reliable_pid_in_range1 (const packet_id_type test,
- const packet_id_type base,
- const unsigned int extent)
+reliable_pid_in_range1(const packet_id_type test,
+ const packet_id_type base,
+ const unsigned int extent)
{
- if (test >= base)
+ if (test >= base)
{
- if (test - base < extent)
- return true;
+ if (test - base < extent)
+ {
+ return true;
+ }
}
- else
+ else
{
- if ((test+0x80000000u) - (base+0x80000000u) < extent)
- return true;
+ if ((test+0x80000000u) - (base+0x80000000u) < extent)
+ {
+ return true;
+ }
}
- return false;
+ return false;
}
/*
* verify that test < base + extent while allowing for base or test wraparound
*/
static inline bool
-reliable_pid_in_range2 (const packet_id_type test,
- const packet_id_type base,
- const unsigned int extent)
+reliable_pid_in_range2(const packet_id_type test,
+ const packet_id_type base,
+ const unsigned int extent)
{
- if (base + extent >= base)
+ if (base + extent >= base)
{
- if (test < base + extent)
- return true;
+ if (test < base + extent)
+ {
+ return true;
+ }
}
- else
+ else
{
- if ((test+0x80000000u) < (base+0x80000000u) + extent)
- return true;
+ if ((test+0x80000000u) < (base+0x80000000u) + extent)
+ {
+ return true;
+ }
}
- return false;
+ 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)
+reliable_pid_min(const packet_id_type p1,
+ const packet_id_type p2)
{
- return !reliable_pid_in_range1 (p1, p2, 0x80000000u);
+ return !reliable_pid_in_range1(p1, p2, 0x80000000u);
}
/* 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)
+reliable_ack_packet_id_present(struct reliable_ack *ack, packet_id_type pid)
{
- int i;
- for (i = 0; i < ack->len; ++i)
- if (ack->packet_id[i] == pid)
- return true;
- return false;
+ int i;
+ for (i = 0; i < ack->len; ++i)
+ if (ack->packet_id[i] == pid)
+ {
+ return true;
+ }
+ return false;
}
/* get a packet_id from buf */
bool
-reliable_ack_read_packet_id (struct buffer *buf, packet_id_type *pid)
+reliable_ack_read_packet_id(struct buffer *buf, packet_id_type *pid)
{
- packet_id_type net_pid;
+ packet_id_type net_pid;
- if (buf_read (buf, &net_pid, sizeof (net_pid)))
+ if (buf_read(buf, &net_pid, sizeof(net_pid)))
{
- *pid = ntohpid (net_pid);
- dmsg (D_REL_DEBUG, "ACK read ID " packet_id_format " (buf->len=%d)",
- (packet_id_print_type)*pid, buf->len);
- return true;
+ *pid = ntohpid(net_pid);
+ dmsg(D_REL_DEBUG, "ACK read ID " packet_id_format " (buf->len=%d)",
+ (packet_id_print_type)*pid, buf->len);
+ return true;
}
- dmsg (D_REL_LOW, "ACK read ID FAILED (buf->len=%d)", buf->len);
- return false;
+ dmsg(D_REL_LOW, "ACK read ID FAILED (buf->len=%d)", buf->len);
+ return false;
}
/* acknowledge a packet_id by adding it to a struct reliable_ack */
bool
-reliable_ack_acknowledge_packet_id (struct reliable_ack *ack, packet_id_type pid)
+reliable_ack_acknowledge_packet_id(struct reliable_ack *ack, packet_id_type pid)
{
- if (!reliable_ack_packet_id_present (ack, pid) && ack->len < RELIABLE_ACK_SIZE)
+ if (!reliable_ack_packet_id_present(ack, pid) && ack->len < RELIABLE_ACK_SIZE)
{
- ack->packet_id[ack->len++] = pid;
- dmsg (D_REL_DEBUG, "ACK acknowledge ID " packet_id_format " (ack->len=%d)",
- (packet_id_print_type)pid, ack->len);
- return true;
+ ack->packet_id[ack->len++] = pid;
+ dmsg(D_REL_DEBUG, "ACK acknowledge ID " packet_id_format " (ack->len=%d)",
+ (packet_id_print_type)pid, ack->len);
+ return true;
}
- dmsg (D_REL_LOW, "ACK acknowledge ID " packet_id_format " FAILED (ack->len=%d)",
- (packet_id_print_type)pid, ack->len);
- return false;
+ dmsg(D_REL_LOW, "ACK acknowledge ID " packet_id_format " FAILED (ack->len=%d)",
+ (packet_id_print_type)pid, ack->len);
+ return false;
}
/* read a packet ID acknowledgement record from buf into ack */
bool
-reliable_ack_read (struct reliable_ack * ack,
- struct buffer * buf, const struct session_id * sid)
+reliable_ack_read(struct reliable_ack *ack,
+ struct buffer *buf, const struct session_id *sid)
{
- struct gc_arena gc = gc_new ();
- int i;
- uint8_t count;
- packet_id_type net_pid;
- packet_id_type pid;
- struct session_id session_id_remote;
-
- if (!buf_read (buf, &count, sizeof (count)))
- goto error;
- for (i = 0; i < count; ++i)
- {
- if (!buf_read (buf, &net_pid, sizeof (net_pid)))
- goto error;
- if (ack->len >= RELIABLE_ACK_SIZE)
- goto error;
- pid = ntohpid (net_pid);
- ack->packet_id[ack->len++] = pid;
- }
- if (count)
- {
- if (!session_id_read (&session_id_remote, buf))
- goto error;
- if (!session_id_defined (&session_id_remote) ||
- !session_id_equal (&session_id_remote, sid))
- {
- dmsg (D_REL_LOW,
- "ACK read BAD SESSION-ID FROM REMOTE, local=%s, remote=%s",
- session_id_print (sid, &gc), session_id_print (&session_id_remote, &gc));
- goto error;
- }
- }
- gc_free (&gc);
- return true;
+ struct gc_arena gc = gc_new();
+ int i;
+ uint8_t count;
+ packet_id_type net_pid;
+ packet_id_type pid;
+ struct session_id session_id_remote;
+
+ if (!buf_read(buf, &count, sizeof(count)))
+ {
+ goto error;
+ }
+ for (i = 0; i < count; ++i)
+ {
+ if (!buf_read(buf, &net_pid, sizeof(net_pid)))
+ {
+ goto error;
+ }
+ if (ack->len >= RELIABLE_ACK_SIZE)
+ {
+ goto error;
+ }
+ pid = ntohpid(net_pid);
+ ack->packet_id[ack->len++] = pid;
+ }
+ if (count)
+ {
+ if (!session_id_read(&session_id_remote, buf))
+ {
+ goto error;
+ }
+ if (!session_id_defined(&session_id_remote)
+ || !session_id_equal(&session_id_remote, sid))
+ {
+ dmsg(D_REL_LOW,
+ "ACK read BAD SESSION-ID FROM REMOTE, local=%s, remote=%s",
+ session_id_print(sid, &gc), session_id_print(&session_id_remote, &gc));
+ goto error;
+ }
+ }
+ gc_free(&gc);
+ return true;
error:
- gc_free (&gc);
- return false;
+ gc_free(&gc);
+ return false;
}
-#define ACK_SIZE(n) (sizeof (uint8_t) + ((n) ? SID_SIZE : 0) + sizeof (packet_id_type) * (n))
+#define ACK_SIZE(n) (sizeof(uint8_t) + ((n) ? SID_SIZE : 0) + sizeof(packet_id_type) * (n))
/* write a packet ID acknowledgement record to buf, */
/* removing all acknowledged entries from ack */
bool
-reliable_ack_write (struct reliable_ack * ack,
- struct buffer * buf,
- const struct session_id * sid, int max, bool prepend)
+reliable_ack_write(struct reliable_ack *ack,
+ struct buffer *buf,
+ const struct session_id *sid, int max, bool prepend)
{
- int i, j;
- uint8_t n;
- struct buffer sub;
+ int i, j;
+ uint8_t n;
+ struct buffer sub;
- n = ack->len;
- if (n > max)
- n = max;
- sub = buf_sub (buf, ACK_SIZE(n), prepend);
- if (!BDEF (&sub))
- goto error;
- ASSERT (buf_write (&sub, &n, sizeof (n)));
- for (i = 0; i < n; ++i)
+ n = ack->len;
+ if (n > max)
{
- packet_id_type pid = ack->packet_id[i];
- packet_id_type net_pid = htonpid (pid);
- ASSERT (buf_write (&sub, &net_pid, sizeof (net_pid)));
- dmsg (D_REL_DEBUG, "ACK write ID " packet_id_format " (ack->len=%d, n=%d)", (packet_id_print_type)pid, ack->len, n);
+ n = max;
}
- if (n)
+ sub = buf_sub(buf, ACK_SIZE(n), prepend);
+ if (!BDEF(&sub))
{
- ASSERT (session_id_defined (sid));
- ASSERT (session_id_write (sid, &sub));
- for (i = 0, j = n; j < ack->len;)
- ack->packet_id[i++] = ack->packet_id[j++];
- ack->len = i;
+ goto error;
+ }
+ ASSERT(buf_write(&sub, &n, sizeof(n)));
+ for (i = 0; i < n; ++i)
+ {
+ packet_id_type pid = ack->packet_id[i];
+ packet_id_type net_pid = htonpid(pid);
+ ASSERT(buf_write(&sub, &net_pid, sizeof(net_pid)));
+ dmsg(D_REL_DEBUG, "ACK write ID " packet_id_format " (ack->len=%d, n=%d)", (packet_id_print_type)pid, ack->len, n);
+ }
+ if (n)
+ {
+ ASSERT(session_id_defined(sid));
+ ASSERT(session_id_write(sid, &sub));
+ for (i = 0, j = n; j < ack->len; )
+ ack->packet_id[i++] = ack->packet_id[j++];
+ ack->len = i;
}
- return true;
+ return true;
error:
- return false;
+ return false;
}
/* add to extra_frame the maximum number of bytes we will need for reliable_ack_write */
void
-reliable_ack_adjust_frame_parameters (struct frame* frame, int max)
+reliable_ack_adjust_frame_parameters(struct frame *frame, int max)
{
- frame_add_to_extra_frame (frame, ACK_SIZE (max));
+ frame_add_to_extra_frame(frame, ACK_SIZE(max));
}
/* print a reliable ACK record coming off the wire */
const char *
-reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc)
+reliable_ack_print(struct buffer *buf, bool verbose, struct gc_arena *gc)
{
- int i;
- uint8_t n_ack;
- struct session_id sid_ack;
- packet_id_type pid;
- struct buffer out = alloc_buf_gc (256, gc);
+ int i;
+ uint8_t n_ack;
+ struct session_id sid_ack;
+ packet_id_type pid;
+ struct buffer out = alloc_buf_gc(256, gc);
- buf_printf (&out, "[");
- if (!buf_read (buf, &n_ack, sizeof (n_ack)))
- goto done;
- for (i = 0; i < n_ack; ++i)
+ buf_printf(&out, "[");
+ if (!buf_read(buf, &n_ack, sizeof(n_ack)))
{
- if (!buf_read (buf, &pid, sizeof (pid)))
- goto done;
- pid = ntohpid (pid);
- buf_printf (&out, " " packet_id_format, (packet_id_print_type)pid);
+ goto done;
}
- if (n_ack)
+ for (i = 0; i < n_ack; ++i)
{
- if (!session_id_read (&sid_ack, buf))
- goto done;
- if (verbose)
- buf_printf (&out, " sid=%s", session_id_print (&sid_ack, gc));
+ if (!buf_read(buf, &pid, sizeof(pid)))
+ {
+ goto done;
+ }
+ pid = ntohpid(pid);
+ buf_printf(&out, " " packet_id_format, (packet_id_print_type)pid);
+ }
+ if (n_ack)
+ {
+ if (!session_id_read(&sid_ack, buf))
+ {
+ goto done;
+ }
+ if (verbose)
+ {
+ buf_printf(&out, " sid=%s", session_id_print(&sid_ack, gc));
+ }
}
- done:
- buf_printf (&out, " ]");
- return BSTR (&out);
+done:
+ buf_printf(&out, " ]");
+ return BSTR(&out);
}
/*
@@ -275,362 +305,378 @@ reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc)
*/
void
-reliable_init (struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
+reliable_init(struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
{
- int i;
+ int i;
- CLEAR (*rel);
- ASSERT (array_size > 0 && array_size <= RELIABLE_CAPACITY);
- rel->hold = hold;
- rel->size = array_size;
- rel->offset = offset;
- for (i = 0; i < rel->size; ++i)
+ CLEAR(*rel);
+ ASSERT(array_size > 0 && array_size <= RELIABLE_CAPACITY);
+ rel->hold = hold;
+ rel->size = array_size;
+ rel->offset = offset;
+ for (i = 0; i < rel->size; ++i)
{
- struct reliable_entry *e = &rel->array[i];
- e->buf = alloc_buf (buf_size);
- ASSERT (buf_init (&e->buf, offset));
+ struct reliable_entry *e = &rel->array[i];
+ e->buf = alloc_buf(buf_size);
+ ASSERT(buf_init(&e->buf, offset));
}
}
void
-reliable_free (struct reliable *rel)
+reliable_free(struct reliable *rel)
{
- int i;
- for (i = 0; i < rel->size; ++i)
+ int i;
+ for (i = 0; i < rel->size; ++i)
{
- struct reliable_entry *e = &rel->array[i];
- free_buf (&e->buf);
+ struct reliable_entry *e = &rel->array[i];
+ free_buf(&e->buf);
}
}
/* no active buffers? */
bool
-reliable_empty (const struct reliable *rel)
+reliable_empty(const struct reliable *rel)
{
- int i;
- for (i = 0; i < rel->size; ++i)
+ int i;
+ for (i = 0; i < rel->size; ++i)
{
- const struct reliable_entry *e = &rel->array[i];
- if (e->active)
- return false;
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ return false;
+ }
}
- return true;
+ return true;
}
/* del acknowledged items from send buf */
void
-reliable_send_purge (struct reliable *rel, struct reliable_ack *ack)
+reliable_send_purge(struct reliable *rel, struct reliable_ack *ack)
{
- int i, j;
- for (i = 0; i < ack->len; ++i)
- {
- packet_id_type pid = ack->packet_id[i];
- for (j = 0; j < rel->size; ++j)
- {
- struct reliable_entry *e = &rel->array[j];
- if (e->active && e->packet_id == pid)
- {
- dmsg (D_REL_DEBUG,
- "ACK received for pid " packet_id_format ", deleting from send buffer",
- (packet_id_print_type)pid);
+ int i, j;
+ for (i = 0; i < ack->len; ++i)
+ {
+ packet_id_type pid = ack->packet_id[i];
+ for (j = 0; j < rel->size; ++j)
+ {
+ struct reliable_entry *e = &rel->array[j];
+ if (e->active && e->packet_id == pid)
+ {
+ dmsg(D_REL_DEBUG,
+ "ACK received for pid " packet_id_format ", deleting from send buffer",
+ (packet_id_print_type)pid);
#if 0
- /* DEBUGGING -- how close were we timing out on ACK failure and resending? */
- {
- if (e->next_try)
- {
- const interval_t wake = e->next_try - now;
- msg (M_INFO, "ACK " packet_id_format ", wake=%d", pid, wake);
- }
- }
+ /* DEBUGGING -- how close were we timing out on ACK failure and resending? */
+ {
+ if (e->next_try)
+ {
+ const interval_t wake = e->next_try - now;
+ msg(M_INFO, "ACK " packet_id_format ", wake=%d", pid, wake);
+ }
+ }
#endif
- e->active = false;
- break;
- }
- }
+ e->active = false;
+ break;
+ }
+ }
}
}
/* print the current sequence of active packet IDs */
static const char *
-reliable_print_ids (const struct reliable *rel, struct gc_arena *gc)
+reliable_print_ids(const struct reliable *rel, struct gc_arena *gc)
{
- struct buffer out = alloc_buf_gc (256, gc);
- int i;
+ struct buffer out = alloc_buf_gc(256, gc);
+ int i;
- buf_printf (&out, "[" packet_id_format "]", (packet_id_print_type)rel->packet_id);
- for (i = 0; i < rel->size; ++i)
+ buf_printf(&out, "[" packet_id_format "]", (packet_id_print_type)rel->packet_id);
+ for (i = 0; i < rel->size; ++i)
{
- const struct reliable_entry *e = &rel->array[i];
- if (e->active)
- buf_printf (&out, " " packet_id_format, (packet_id_print_type)e->packet_id);
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ buf_printf(&out, " " packet_id_format, (packet_id_print_type)e->packet_id);
+ }
}
- return BSTR (&out);
+ return BSTR(&out);
}
/* true if at least one free buffer available */
bool
-reliable_can_get (const struct reliable *rel)
+reliable_can_get(const struct reliable *rel)
{
- struct gc_arena gc = gc_new ();
- int i;
- for (i = 0; i < rel->size; ++i)
- {
- const struct reliable_entry *e = &rel->array[i];
- if (!e->active)
- return true;
- }
- dmsg (D_REL_LOW, "ACK no free receive buffer available: %s", reliable_print_ids (rel, &gc));
- gc_free (&gc);
- return false;
+ struct gc_arena gc = gc_new();
+ int i;
+ for (i = 0; i < rel->size; ++i)
+ {
+ const struct reliable_entry *e = &rel->array[i];
+ if (!e->active)
+ {
+ return true;
+ }
+ }
+ dmsg(D_REL_LOW, "ACK no free receive buffer available: %s", reliable_print_ids(rel, &gc));
+ gc_free(&gc);
+ return false;
}
/* make sure that incoming packet ID isn't a replay */
bool
-reliable_not_replay (const struct reliable *rel, packet_id_type id)
+reliable_not_replay(const struct reliable *rel, packet_id_type id)
{
- struct gc_arena gc = gc_new ();
- int i;
- if (reliable_pid_min (id, rel->packet_id))
- goto bad;
- for (i = 0; i < rel->size; ++i)
+ struct gc_arena gc = gc_new();
+ int i;
+ if (reliable_pid_min(id, rel->packet_id))
{
- const struct reliable_entry *e = &rel->array[i];
- if (e->active && e->packet_id == id)
- goto bad;
+ goto bad;
}
- gc_free (&gc);
- return true;
+ for (i = 0; i < rel->size; ++i)
+ {
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active && e->packet_id == id)
+ {
+ goto bad;
+ }
+ }
+ gc_free(&gc);
+ return true;
- bad:
- dmsg (D_REL_DEBUG, "ACK " packet_id_format " is a replay: %s", (packet_id_print_type)id, reliable_print_ids (rel, &gc));
- gc_free (&gc);
- return false;
+bad:
+ dmsg(D_REL_DEBUG, "ACK " packet_id_format " is a replay: %s", (packet_id_print_type)id, reliable_print_ids(rel, &gc));
+ gc_free(&gc);
+ return false;
}
/* make sure that incoming packet ID won't deadlock the receive buffer */
bool
-reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id)
+reliable_wont_break_sequentiality(const struct reliable *rel, packet_id_type id)
{
- struct gc_arena gc = gc_new ();
+ struct gc_arena gc = gc_new();
- const int ret = reliable_pid_in_range2 (id, rel->packet_id, rel->size);
+ const int ret = reliable_pid_in_range2(id, rel->packet_id, rel->size);
- if (!ret)
+ if (!ret)
{
- dmsg (D_REL_LOW, "ACK " packet_id_format " breaks sequentiality: %s",
- (packet_id_print_type)id, reliable_print_ids (rel, &gc));
+ dmsg(D_REL_LOW, "ACK " packet_id_format " breaks sequentiality: %s",
+ (packet_id_print_type)id, reliable_print_ids(rel, &gc));
}
- 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);
+ 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;
+ gc_free(&gc);
+ return ret;
}
/* grab a free buffer */
struct buffer *
-reliable_get_buf (struct reliable *rel)
+reliable_get_buf(struct reliable *rel)
{
- int i;
- for (i = 0; i < rel->size; ++i)
+ int i;
+ for (i = 0; i < rel->size; ++i)
{
- struct reliable_entry *e = &rel->array[i];
- if (!e->active)
- {
- ASSERT (buf_init (&e->buf, rel->offset));
- return &e->buf;
- }
+ struct reliable_entry *e = &rel->array[i];
+ if (!e->active)
+ {
+ ASSERT(buf_init(&e->buf, rel->offset));
+ return &e->buf;
+ }
}
- return NULL;
+ return NULL;
}
/* grab a free buffer, fail if buffer clogged by unacknowledged low packet IDs */
struct buffer *
-reliable_get_buf_output_sequenced (struct reliable *rel)
+reliable_get_buf_output_sequenced(struct reliable *rel)
{
- struct gc_arena gc = gc_new ();
- int i;
- packet_id_type min_id = 0;
- bool min_id_defined = false;
- struct buffer *ret = NULL;
+ struct gc_arena gc = gc_new();
+ int i;
+ packet_id_type min_id = 0;
+ bool min_id_defined = false;
+ struct buffer *ret = NULL;
- /* find minimum active packet_id */
- for (i = 0; i < rel->size; ++i)
+ /* find minimum active packet_id */
+ for (i = 0; i < rel->size; ++i)
{
- const struct reliable_entry *e = &rel->array[i];
- if (e->active)
- {
- if (!min_id_defined || reliable_pid_min (e->packet_id, min_id))
- {
- min_id_defined = true;
- min_id = e->packet_id;
- }
- }
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ if (!min_id_defined || reliable_pid_min(e->packet_id, min_id))
+ {
+ min_id_defined = true;
+ min_id = e->packet_id;
+ }
+ }
}
- if (!min_id_defined || reliable_pid_in_range1 (rel->packet_id, min_id, rel->size))
+ if (!min_id_defined || reliable_pid_in_range1(rel->packet_id, min_id, rel->size))
{
- ret = reliable_get_buf (rel);
+ ret = reliable_get_buf(rel);
}
- else
+ else
{
- dmsg (D_REL_LOW, "ACK output sequence broken: %s", reliable_print_ids (rel, &gc));
+ dmsg(D_REL_LOW, "ACK output sequence broken: %s", reliable_print_ids(rel, &gc));
}
- gc_free (&gc);
- return ret;
+ gc_free(&gc);
+ return ret;
}
/* get active buffer for next sequentially increasing key ID */
struct buffer *
-reliable_get_buf_sequenced (struct reliable *rel)
+reliable_get_buf_sequenced(struct reliable *rel)
{
- int i;
- for (i = 0; i < rel->size; ++i)
+ int i;
+ for (i = 0; i < rel->size; ++i)
{
- struct reliable_entry *e = &rel->array[i];
- if (e->active && e->packet_id == rel->packet_id)
- {
- return &e->buf;
- }
+ struct reliable_entry *e = &rel->array[i];
+ if (e->active && e->packet_id == rel->packet_id)
+ {
+ return &e->buf;
+ }
}
- return NULL;
+ return NULL;
}
/* return true if reliable_send would return a non-NULL result */
bool
-reliable_can_send (const struct reliable *rel)
+reliable_can_send(const struct reliable *rel)
{
- struct gc_arena gc = gc_new ();
- int i;
- int n_active = 0, n_current = 0;
- for (i = 0; i < rel->size; ++i)
- {
- const struct reliable_entry *e = &rel->array[i];
- if (e->active)
- {
- ++n_active;
- if (now >= e->next_try)
- ++n_current;
- }
- }
- dmsg (D_REL_DEBUG, "ACK reliable_can_send active=%d current=%d : %s",
- n_active,
- n_current,
- reliable_print_ids (rel, &gc));
-
- gc_free (&gc);
- return n_current > 0 && !rel->hold;
+ struct gc_arena gc = gc_new();
+ int i;
+ int n_active = 0, n_current = 0;
+ for (i = 0; i < rel->size; ++i)
+ {
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ ++n_active;
+ if (now >= e->next_try)
+ {
+ ++n_current;
+ }
+ }
+ }
+ dmsg(D_REL_DEBUG, "ACK reliable_can_send active=%d current=%d : %s",
+ n_active,
+ n_current,
+ reliable_print_ids(rel, &gc));
+
+ gc_free(&gc);
+ return n_current > 0 && !rel->hold;
}
#ifdef EXPONENTIAL_BACKOFF
/* return a unique point-in-time to trigger retry */
static time_t
-reliable_unique_retry (struct reliable *rel, time_t retry)
+reliable_unique_retry(struct reliable *rel, time_t retry)
{
- int i;
- while (true)
- {
- for (i = 0; i < rel->size; ++i)
- {
- struct reliable_entry *e = &rel->array[i];
- if (e->active && e->next_try == retry)
- goto again;
- }
- break;
- again:
- ++retry;
- }
- return retry;
+ int i;
+ while (true)
+ {
+ for (i = 0; i < rel->size; ++i)
+ {
+ struct reliable_entry *e = &rel->array[i];
+ if (e->active && e->next_try == retry)
+ {
+ goto again;
+ }
+ }
+ break;
+again:
+ ++retry;
+ }
+ return retry;
}
-#endif
+#endif /* ifdef EXPONENTIAL_BACKOFF */
/* return next buffer to send to remote */
struct buffer *
-reliable_send (struct reliable *rel, int *opcode)
+reliable_send(struct reliable *rel, int *opcode)
{
- int i;
- struct reliable_entry *best = NULL;
- const time_t local_now = now;
+ int i;
+ struct reliable_entry *best = NULL;
+ const time_t local_now = now;
- for (i = 0; i < rel->size; ++i)
+ for (i = 0; i < rel->size; ++i)
{
- struct reliable_entry *e = &rel->array[i];
- if (e->active && local_now >= e->next_try)
- {
- if (!best || reliable_pid_min (e->packet_id, best->packet_id))
- best = e;
- }
+ struct reliable_entry *e = &rel->array[i];
+ if (e->active && local_now >= e->next_try)
+ {
+ if (!best || reliable_pid_min(e->packet_id, best->packet_id))
+ {
+ best = e;
+ }
+ }
}
- if (best)
+ if (best)
{
#ifdef EXPONENTIAL_BACKOFF
- /* exponential backoff */
- best->next_try = reliable_unique_retry (rel, local_now + best->timeout);
- best->timeout *= 2;
+ /* exponential backoff */
+ best->next_try = reliable_unique_retry(rel, local_now + best->timeout);
+ best->timeout *= 2;
#else
- /* constant timeout, no backoff */
- best->next_try = local_now + best->timeout;
+ /* constant timeout, no backoff */
+ best->next_try = local_now + best->timeout;
#endif
- *opcode = best->opcode;
- dmsg (D_REL_DEBUG, "ACK reliable_send ID " packet_id_format " (size=%d to=%d)",
- (packet_id_print_type)best->packet_id, best->buf.len,
- (int)(best->next_try - local_now));
- return &best->buf;
+ *opcode = best->opcode;
+ dmsg(D_REL_DEBUG, "ACK reliable_send ID " packet_id_format " (size=%d to=%d)",
+ (packet_id_print_type)best->packet_id, best->buf.len,
+ (int)(best->next_try - local_now));
+ return &best->buf;
}
- return NULL;
+ return NULL;
}
/* schedule all pending packets for immediate retransmit */
void
-reliable_schedule_now (struct reliable *rel)
+reliable_schedule_now(struct reliable *rel)
{
- int i;
- dmsg (D_REL_DEBUG, "ACK reliable_schedule_now");
- rel->hold = false;
- for (i = 0; i < rel->size; ++i)
- {
- struct reliable_entry *e = &rel->array[i];
- if (e->active)
- {
- e->next_try = now;
- e->timeout = rel->initial_timeout;
- }
+ int i;
+ dmsg(D_REL_DEBUG, "ACK reliable_schedule_now");
+ rel->hold = false;
+ for (i = 0; i < rel->size; ++i)
+ {
+ struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ e->next_try = now;
+ e->timeout = rel->initial_timeout;
+ }
}
}
/* in how many seconds should we wake up to check for timeout */
/* if we return BIG_TIMEOUT, nothing to wait for */
interval_t
-reliable_send_timeout (const struct reliable *rel)
+reliable_send_timeout(const struct reliable *rel)
{
- struct gc_arena gc = gc_new ();
- interval_t ret = BIG_TIMEOUT;
- int i;
- const time_t local_now = now;
-
- for (i = 0; i < rel->size; ++i)
- {
- const struct reliable_entry *e = &rel->array[i];
- if (e->active)
- {
- if (e->next_try <= local_now)
- {
- ret = 0;
- break;
- }
- else
- {
- ret = min_int (ret, e->next_try - local_now);
- }
- }
- }
-
- dmsg (D_REL_DEBUG, "ACK reliable_send_timeout %d %s",
- (int) ret,
- reliable_print_ids (rel, &gc));
-
- gc_free (&gc);
- return ret;
+ struct gc_arena gc = gc_new();
+ interval_t ret = BIG_TIMEOUT;
+ int i;
+ const time_t local_now = now;
+
+ for (i = 0; i < rel->size; ++i)
+ {
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ if (e->next_try <= local_now)
+ {
+ ret = 0;
+ break;
+ }
+ else
+ {
+ ret = min_int(ret, e->next_try - local_now);
+ }
+ }
+ }
+
+ dmsg(D_REL_DEBUG, "ACK reliable_send_timeout %d %s",
+ (int) ret,
+ reliable_print_ids(rel, &gc));
+
+ gc_free(&gc);
+ return ret;
}
/*
@@ -638,31 +684,31 @@ reliable_send_timeout (const struct reliable *rel)
*/
void
-reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf,
- packet_id_type pid, int opcode)
+reliable_mark_active_incoming(struct reliable *rel, struct buffer *buf,
+ packet_id_type pid, int opcode)
{
- int i;
- for (i = 0; i < rel->size; ++i)
+ int i;
+ for (i = 0; i < rel->size; ++i)
{
- struct reliable_entry *e = &rel->array[i];
- if (buf == &e->buf)
- {
- e->active = true;
+ struct reliable_entry *e = &rel->array[i];
+ if (buf == &e->buf)
+ {
+ e->active = true;
- /* packets may not arrive in sequential order */
- e->packet_id = pid;
+ /* packets may not arrive in sequential order */
+ e->packet_id = pid;
- /* check for replay */
- ASSERT (!reliable_pid_min (pid, rel->packet_id));
+ /* check for replay */
+ ASSERT(!reliable_pid_min(pid, rel->packet_id));
- e->opcode = opcode;
- e->next_try = 0;
- e->timeout = 0;
- dmsg (D_REL_DEBUG, "ACK mark active incoming ID " packet_id_format, (packet_id_print_type)e->packet_id);
- return;
- }
+ e->opcode = opcode;
+ e->next_try = 0;
+ e->timeout = 0;
+ dmsg(D_REL_DEBUG, "ACK mark active incoming ID " packet_id_format, (packet_id_print_type)e->packet_id);
+ return;
+ }
}
- ASSERT (0); /* buf not found in rel */
+ ASSERT(0); /* buf not found in rel */
}
/*
@@ -670,88 +716,92 @@ reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf,
*/
void
-reliable_mark_active_outgoing (struct reliable *rel, struct buffer *buf, int opcode)
+reliable_mark_active_outgoing(struct reliable *rel, struct buffer *buf, int opcode)
{
- int i;
- for (i = 0; i < rel->size; ++i)
- {
- struct reliable_entry *e = &rel->array[i];
- if (buf == &e->buf)
- {
- /* Write mode, increment packet_id (i.e. sequence number)
- linearly and prepend id to packet */
- packet_id_type net_pid;
- e->packet_id = rel->packet_id++;
- net_pid = htonpid (e->packet_id);
- ASSERT (buf_write_prepend (buf, &net_pid, sizeof (net_pid)));
- e->active = true;
- e->opcode = opcode;
- e->next_try = 0;
- e->timeout = rel->initial_timeout;
- dmsg (D_REL_DEBUG, "ACK mark active outgoing ID " packet_id_format, (packet_id_print_type)e->packet_id);
- return;
- }
- }
- ASSERT (0); /* buf not found in rel */
+ int i;
+ for (i = 0; i < rel->size; ++i)
+ {
+ struct reliable_entry *e = &rel->array[i];
+ if (buf == &e->buf)
+ {
+ /* Write mode, increment packet_id (i.e. sequence number)
+ * linearly and prepend id to packet */
+ packet_id_type net_pid;
+ e->packet_id = rel->packet_id++;
+ net_pid = htonpid(e->packet_id);
+ ASSERT(buf_write_prepend(buf, &net_pid, sizeof(net_pid)));
+ e->active = true;
+ e->opcode = opcode;
+ e->next_try = 0;
+ e->timeout = rel->initial_timeout;
+ dmsg(D_REL_DEBUG, "ACK mark active outgoing ID " packet_id_format, (packet_id_print_type)e->packet_id);
+ return;
+ }
+ }
+ ASSERT(0); /* buf not found in rel */
}
/* delete a buffer previously activated by reliable_mark_active() */
void
-reliable_mark_deleted (struct reliable *rel, struct buffer *buf, bool inc_pid)
+reliable_mark_deleted(struct reliable *rel, struct buffer *buf, bool inc_pid)
{
- int i;
- for (i = 0; i < rel->size; ++i)
- {
- struct reliable_entry *e = &rel->array[i];
- if (buf == &e->buf)
- {
- e->active = false;
- if (inc_pid)
- rel->packet_id = e->packet_id + 1;
- return;
- }
- }
- ASSERT (0);
+ int i;
+ for (i = 0; i < rel->size; ++i)
+ {
+ struct reliable_entry *e = &rel->array[i];
+ if (buf == &e->buf)
+ {
+ e->active = false;
+ if (inc_pid)
+ {
+ rel->packet_id = e->packet_id + 1;
+ }
+ return;
+ }
+ }
+ ASSERT(0);
}
#if 0
void
-reliable_ack_debug_print (const struct reliable_ack *ack, char *desc)
+reliable_ack_debug_print(const struct reliable_ack *ack, char *desc)
{
- int i;
+ int i;
- printf ("********* struct reliable_ack %s\n", desc);
- for (i = 0; i < ack->len; ++i)
+ printf("********* struct reliable_ack %s\n", desc);
+ for (i = 0; i < ack->len; ++i)
{
- printf (" %d: " packet_id_format "\n", i, (packet_id_print_type) ack->packet_id[i]);
+ printf(" %d: " packet_id_format "\n", i, (packet_id_print_type) ack->packet_id[i]);
}
}
void
-reliable_debug_print (const struct reliable *rel, char *desc)
+reliable_debug_print(const struct reliable *rel, char *desc)
{
- int i;
- update_time ();
-
- printf ("********* struct reliable %s\n", desc);
- printf (" initial_timeout=%d\n", (int)rel->initial_timeout);
- printf (" packet_id=" packet_id_format "\n", rel->packet_id);
- printf (" now=" time_format "\n", now);
- for (i = 0; i < rel->size; ++i)
- {
- const struct reliable_entry *e = &rel->array[i];
- if (e->active)
- {
- printf (" %d: packet_id=" packet_id_format " len=%d", i, e->packet_id, e->buf.len);
- printf (" next_try=" time_format, e->next_try);
- printf ("\n");
- }
+ int i;
+ update_time();
+
+ printf("********* struct reliable %s\n", desc);
+ printf(" initial_timeout=%d\n", (int)rel->initial_timeout);
+ printf(" packet_id=" packet_id_format "\n", rel->packet_id);
+ printf(" now=" time_format "\n", now);
+ for (i = 0; i < rel->size; ++i)
+ {
+ const struct reliable_entry *e = &rel->array[i];
+ if (e->active)
+ {
+ printf(" %d: packet_id=" packet_id_format " len=%d", i, e->packet_id, e->buf.len);
+ printf(" next_try=" time_format, e->next_try);
+ printf("\n");
+ }
}
}
-#endif
+#endif /* if 0 */
-#else
-static void dummy(void) {}
+#else /* ifdef ENABLE_CRYPTO */
+static void
+dummy(void) {
+}
#endif /* ENABLE_CRYPTO */