54 const unsigned int extent)
64 const unsigned int extent)
66 if (base + extent >= base)
68 if (test < base + extent)
75 if ((test + 0x80000000u) < (base + 0x80000000u) + extent)
97 for (
int i = 0; i < ack->
len; ++i)
113 if (
buf_read(buf, &net_pid,
sizeof(net_pid)))
157 dmsg(
D_REL_LOW,
"ACK read BAD SESSION-ID FROM REMOTE, local=%s, remote=%s",
172 if (!
buf_read(buf, &count,
sizeof(count)))
176 for (
int i = 0; i < count; ++i)
179 if (!
buf_read(buf, &net_pid,
sizeof(net_pid)))
208 for (
int i = n - 1; i >= 0; i--)
213 if (ack_mru->
len == 0)
219 bool idfound =
false;
224 for (
int j = 0; j < ack_mru->
len; j++)
249 const struct session_id *sid,
int max,
bool prepend)
290 for (
i = 0,
j = n;
j <
ack->len;)
292 ack->packet_id[
i++] =
ack->packet_id[
j++];
353 rel->
size = array_size;
355 for (
int i = 0; i < rel->
size; ++i)
370 for (
int i = 0; i < rel->
size; ++i)
382 for (
int i = 0; i < rel->
size; ++i)
404 unsigned int out_of_window = 0;
407 for (
int i = 0; i < ack->
len; ++i)
414 if (out_of_window == 0)
416 first_out_of_window = pid;
422 for (
int j = 0; j < rel->
size; ++j)
456 if (out_of_window > 0)
458 (void)first_out_of_window;
459 dmsg(
D_REL_LOW,
"ACK contained %u ids outside the send window, "
473 for (
int i = 0;
i <
rel->size; ++
i)
489 for (
int i = 0; i < rel->
size; ++i)
498 dmsg(
D_REL_LOW,
"ACK no free receive buffer available: %s", reliable_print_ids(rel, &
gc));
512 for (
int i = 0; i < rel->
size; ++i)
525 reliable_print_ids(rel, &
gc));
553 for (
int i = 0;
i <
rel->size; ++
i)
569 bool min_id_defined =
false;
572 for (
int i = 0; i < rel->
size; ++i)
579 min_id_defined =
true;
602 for (
int i = 0;
i <
rel->size; ++
i)
609 min_id_defined =
true;
622 dmsg(
D_REL_LOW,
"ACK output sequence broken: %s", reliable_print_ids(rel, &
gc));
632 for (
int i = 0; i < rel->
size; ++i)
648 int n_active = 0, n_current = 0;
649 for (
int i = 0; i < rel->
size; ++i)
662 dmsg(
D_REL_DEBUG,
"ACK reliable_can_send active=%d current=%d : %s", n_active, n_current,
663 reliable_print_ids(rel, &
gc));
666 return n_current > 0 && !rel->
hold;
674 const time_t local_now =
now;
676 for (
int i = 0; i < rel->
size; ++i)
697 "initial reliable timeout overflows when shifted");
702 if (best->
timeout < max_timeout)
723 for (
int i = 0; i < rel->
size; ++i)
741 const time_t local_now =
now;
743 for (
int i = 0; i < rel->
size; ++i)
760 dmsg(
D_REL_DEBUG,
"ACK reliable_send_timeout %d %s", (
int)ret, reliable_print_ids(rel, &
gc));
774 for (
int i = 0; i < rel->
size; ++i)
806 for (
int i = 0; i < rel->
size; ++i)
833 for (
int i = 0; i < rel->
size; ++i)
851 printf(
"********* struct reliable_ack %s\n", desc);
852 for (
int i = 0; i < ack->
len; ++i)
863 printf(
"********* struct reliable %s\n", desc);
866 printf(
" now=%" PRIi64
"\n", (int64_t)
now);
867 for (
int i = 0; i < rel->
size; ++i)
873 printf(
" next_try=%" PRIi64, (int64_t)e->
next_try);
void free_buf(struct buffer *buf)
Free the memory allocated for a buffer.
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Return a sub-buffer of another buffer.
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
struct buffer alloc_buf(size_t size)
Allocate a buffer of the given size.
Buffer management functions and garbage collection.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Prepend data to a buffer.
static bool buf_read(struct buffer *src, void *dest, int size)
Read bytes from the front of a buffer into a caller-supplied destination.
#define BDEF(buf)
Return true iff the buffer is defined (has non-NULL data pointer).
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Append data to a buffer.
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Append a uint8_t to a buffer.
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
#define buf_init(buf, offset)
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
void reliable_free(struct reliable *rel)
Free allocated memory associated with a reliable structure and the pointer itself.
bool reliable_ack_read(struct reliable_ack *ack, struct buffer *buf, const struct session_id *sid)
Read an acknowledgment record from a received packet.
struct buffer * reliable_get_buf_output_sequenced(struct reliable *rel)
Get the buffer of free reliable entry and check whether the outgoing acknowledgment sequence is still...
void reliable_schedule_now(struct reliable *rel)
Reschedule all entries of a reliable structure to be ready for (re)sending immediately.
void reliable_ack_debug_print(const struct reliable_ack *ack, char *desc)
bool reliable_ack_read_packet_id(struct buffer *buf, packet_id_type *pid)
Read the packet ID of a received packet.
void reliable_mark_active_incoming(struct reliable *rel, struct buffer *buf, packet_id_type pid, int opcode)
Mark the reliable entry associated with the given buffer as active incoming.
void reliable_mark_active_outgoing(struct reliable *rel, struct buffer *buf, int opcode)
Mark the reliable entry associated with the given buffer as active outgoing.
const char * reliable_ack_print(struct buffer *buf, bool verbose, struct gc_arena *gc)
bool reliable_ack_acknowledge_packet_id(struct reliable_ack *ack, packet_id_type pid)
Record a packet ID for later acknowledgment.
#define RELIABLE_MAX_INITIAL_TIMEOUT
Maximum initial timeout (–tls-timeout) we accept.
bool reliable_ack_parse(struct buffer *buf, struct reliable_ack *ack, struct session_id *session_id_remote)
Parse an acknowledgment record from a received packet.
#define RELIABLE_MAX_TIMEOUT_SHIFT
Maximum shift or doubling in exponential backoff we allow.
bool reliable_ack_write(struct reliable_ack *ack, struct reliable_ack *ack_mru, struct buffer *buf, const struct session_id *sid, int max, bool prepend)
Write a packet ID acknowledgment record to a buffer.
#define N_ACK_RETRANSMIT
We retry sending a packet early if this many later packets have been ACKed.
int validate_packet_id_window(struct reliable *rel, packet_id_type pid)
check that pid is inside the window of possible outstanding packets of size RELIABLE_CAPACITY,...
bool reliable_can_get(const struct reliable *rel)
Check whether a reliable structure has any free buffers available for use.
void reliable_send_purge(struct reliable *rel, const struct reliable_ack *ack)
Remove acknowledged packets from a reliable structure.
struct buffer * reliable_get_buf(struct reliable *rel)
Get the buffer of a free reliable entry in which to store a packet.
struct buffer * reliable_send(struct reliable *rel, int *opcode)
Get the next packet to send to the remote peer.
bool reliable_can_send(const struct reliable *rel)
Check whether a reliable structure has any active entries ready to be (re)sent.
bool reliable_empty(const struct reliable *rel)
Check whether a reliable structure is empty.
void reliable_debug_print(const struct reliable *rel, char *desc)
bool reliable_not_replay(const struct reliable *rel, packet_id_type id)
Check that a received packet's ID is not a replay.
#define RELIABLE_ACK_SIZE
The maximum number of packet IDs waiting to be acknowledged which can be stored in one reliable_ack s...
interval_t reliable_send_timeout(const struct reliable *rel)
Determined how many seconds until the earliest resend should be attempted.
#define RELIABLE_CAPACITY
The maximum number of packets that the reliability layer for one VPN tunnel in one direction can stor...
struct reliable_entry * reliable_get_entry_sequenced(struct reliable *rel)
Get the buffer of the next sequential and active entry.
void reliable_init(struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
Initialize a reliable structure.
void copy_acks_to_mru(struct reliable_ack *ack, struct reliable_ack *ack_mru, int n)
Copies the first n acks from ack to ack_mru.
void reliable_mark_deleted(struct reliable *rel, struct buffer *buf)
Remove an entry from a reliable structure.
int reliable_get_num_output_sequenced_available(struct reliable *rel)
Counts the number of free buffers in output that can be potentially used for sending.
bool reliable_wont_break_sequentiality(const struct reliable *rel, packet_id_type id)
Check that a received packet's ID can safely be stored in the reliable structure's processing window.
static int min_int(int x, int y)
static void update_time(void)
uint64_t packet_id_print_type
static packet_id_type subtract_pid(const packet_id_type test, const packet_id_type base)
static bool reliable_ack_packet_id_present(struct reliable_ack *ack, packet_id_type pid)
static bool reliable_pid_in_range1(const packet_id_type test, const packet_id_type base, const unsigned int extent)
static bool reliable_pid_min(const packet_id_type p1, const packet_id_type p2)
static bool reliable_pid_in_range2(const packet_id_type test, const packet_id_type base, const unsigned int extent)
Reliability Layer module header file.
const char * session_id_print(const struct session_id *sid, struct gc_arena *gc)
static bool session_id_write(const struct session_id *sid, struct buffer *buf)
static bool session_id_equal(const struct session_id *sid1, const struct session_id *sid2)
static bool session_id_defined(const struct session_id *sid1)
static bool session_id_read(struct session_id *sid, struct buffer *buf)
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
The acknowledgment structure in which packet IDs are stored for later acknowledgment.
packet_id_type packet_id[RELIABLE_ACK_SIZE]
The structure in which the reliability layer stores a single incoming or outgoing packet.
The reliability layer storage structure for one VPN tunnel's control channel in one direction.
struct reliable_entry array[RELIABLE_CAPACITY]
packet_id_type packet_id
Packet ID for the next packet to be sent out.
interval_t initial_timeout
int offset
Offset of the bufs in the reliable_entry array.