OpenVPN
reliable.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /*
25  * These routines implement a reliability layer on top of UDP,
26  * so that SSL/TLS can be run over UDP.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
34 
35 #include "syshead.h"
36 
37 #include "buffer.h"
38 #include "error.h"
39 #include "common.h"
40 #include "reliable.h"
41 
42 #include "memdbg.h"
43 
44 /*
45  * verify that test - base < extent while allowing for base or test wraparound
46  */
47 static inline bool
49  const packet_id_type base,
50  const unsigned int extent)
51 {
52  if (test >= base)
53  {
54  if (test - base < extent)
55  {
56  return true;
57  }
58  }
59  else
60  {
61  if ((test+0x80000000u) - (base+0x80000000u) < extent)
62  {
63  return true;
64  }
65  }
66 
67  return false;
68 }
69 
70 /*
71  * verify that test < base + extent while allowing for base or test wraparound
72  */
73 static inline bool
75  const packet_id_type base,
76  const unsigned int extent)
77 {
78  if (base + extent >= base)
79  {
80  if (test < base + extent)
81  {
82  return true;
83  }
84  }
85  else
86  {
87  if ((test+0x80000000u) < (base+0x80000000u) + extent)
88  {
89  return true;
90  }
91  }
92 
93  return false;
94 }
95 
96 /*
97  * verify that p1 < p2 while allowing for p1 or p2 wraparound
98  */
99 static inline bool
101  const packet_id_type p2)
102 {
103  return !reliable_pid_in_range1(p1, p2, 0x80000000u);
104 }
105 
106 /* check if a particular packet_id is present in ack */
107 static inline bool
109 {
110  int i;
111  for (i = 0; i < ack->len; ++i)
112  {
113  if (ack->packet_id[i] == pid)
114  {
115  return true;
116  }
117  }
118  return false;
119 }
120 
121 /* get a packet_id from buf */
122 bool
124 {
125  packet_id_type net_pid;
126 
127  if (buf_read(buf, &net_pid, sizeof(net_pid)))
128  {
129  *pid = ntohpid(net_pid);
130  dmsg(D_REL_DEBUG, "ACK read ID " packet_id_format " (buf->len=%d)",
131  (packet_id_print_type)*pid, buf->len);
132  return true;
133  }
134 
135  dmsg(D_REL_LOW, "ACK read ID FAILED (buf->len=%d)", buf->len);
136  return false;
137 }
138 
139 /* acknowledge a packet_id by adding it to a struct reliable_ack */
140 bool
142 {
143  if (!reliable_ack_packet_id_present(ack, pid) && ack->len < RELIABLE_ACK_SIZE)
144  {
145  ack->packet_id[ack->len++] = pid;
146  dmsg(D_REL_DEBUG, "ACK acknowledge ID " packet_id_format " (ack->len=%d)",
147  (packet_id_print_type)pid, ack->len);
148  return true;
149  }
150 
151  dmsg(D_REL_LOW, "ACK acknowledge ID " packet_id_format " FAILED (ack->len=%d)",
152  (packet_id_print_type)pid, ack->len);
153  return false;
154 }
155 
156 /* read a packet ID acknowledgement record from buf into ack */
157 bool
159  struct buffer *buf, const struct session_id *sid)
160 {
161  struct gc_arena gc = gc_new();
162  int i;
163  uint8_t count;
164  packet_id_type net_pid;
165  packet_id_type pid;
166  struct session_id session_id_remote;
167 
168  if (!buf_read(buf, &count, sizeof(count)))
169  {
170  goto error;
171  }
172  for (i = 0; i < count; ++i)
173  {
174  if (!buf_read(buf, &net_pid, sizeof(net_pid)))
175  {
176  goto error;
177  }
178  if (ack->len >= RELIABLE_ACK_SIZE)
179  {
180  goto error;
181  }
182  pid = ntohpid(net_pid);
183  ack->packet_id[ack->len++] = pid;
184  }
185  if (count)
186  {
187  if (!session_id_read(&session_id_remote, buf))
188  {
189  goto error;
190  }
191  if (!session_id_defined(&session_id_remote)
192  || !session_id_equal(&session_id_remote, sid))
193  {
194  dmsg(D_REL_LOW,
195  "ACK read BAD SESSION-ID FROM REMOTE, local=%s, remote=%s",
196  session_id_print(sid, &gc), session_id_print(&session_id_remote, &gc));
197  goto error;
198  }
199  }
200  gc_free(&gc);
201  return true;
202 
203 error:
204  gc_free(&gc);
205  return false;
206 }
207 
208 #define ACK_SIZE(n) (sizeof(uint8_t) + ((n) ? SID_SIZE : 0) + sizeof(packet_id_type) * (n))
209 
210 /* write a packet ID acknowledgement record to buf, */
211 /* removing all acknowledged entries from ack */
212 bool
214  struct buffer *buf,
215  const struct session_id *sid, int max, bool prepend)
216 {
217  int i, j;
218  uint8_t n;
219  struct buffer sub;
220 
221  n = ack->len;
222  if (n > max)
223  {
224  n = max;
225  }
226  sub = buf_sub(buf, ACK_SIZE(n), prepend);
227  if (!BDEF(&sub))
228  {
229  goto error;
230  }
231  ASSERT(buf_write(&sub, &n, sizeof(n)));
232  for (i = 0; i < n; ++i)
233  {
234  packet_id_type pid = ack->packet_id[i];
235  packet_id_type net_pid = htonpid(pid);
236  ASSERT(buf_write(&sub, &net_pid, sizeof(net_pid)));
237  dmsg(D_REL_DEBUG, "ACK write ID " packet_id_format " (ack->len=%d, n=%d)", (packet_id_print_type)pid, ack->len, n);
238  }
239  if (n)
240  {
242  ASSERT(session_id_write(sid, &sub));
243  for (i = 0, j = n; j < ack->len; )
244  {
245  ack->packet_id[i++] = ack->packet_id[j++];
246  }
247  ack->len = i;
248  }
249 
250  return true;
251 
252 error:
253  return false;
254 }
255 
256 /* add to extra_frame the maximum number of bytes we will need for reliable_ack_write */
257 void
259 {
260  frame_add_to_extra_frame(frame, ACK_SIZE(max));
261 }
262 
263 /* print a reliable ACK record coming off the wire */
264 const char *
265 reliable_ack_print(struct buffer *buf, bool verbose, struct gc_arena *gc)
266 {
267  int i;
268  uint8_t n_ack;
269  struct session_id sid_ack;
270  packet_id_type pid;
271  struct buffer out = alloc_buf_gc(256, gc);
272 
273  buf_printf(&out, "[");
274  if (!buf_read(buf, &n_ack, sizeof(n_ack)))
275  {
276  goto done;
277  }
278  for (i = 0; i < n_ack; ++i)
279  {
280  if (!buf_read(buf, &pid, sizeof(pid)))
281  {
282  goto done;
283  }
284  pid = ntohpid(pid);
286  }
287  if (n_ack)
288  {
289  if (!session_id_read(&sid_ack, buf))
290  {
291  goto done;
292  }
293  if (verbose)
294  {
295  buf_printf(&out, " sid=%s", session_id_print(&sid_ack, gc));
296  }
297  }
298 
299 done:
300  buf_printf(&out, " ]");
301  return BSTR(&out);
302 }
303 
304 /*
305  * struct reliable member functions.
306  */
307 
308 void
309 reliable_init(struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
310 {
311  int i;
312 
313  CLEAR(*rel);
314  ASSERT(array_size > 0 && array_size <= RELIABLE_CAPACITY);
315  rel->hold = hold;
316  rel->size = array_size;
317  rel->offset = offset;
318  for (i = 0; i < rel->size; ++i)
319  {
320  struct reliable_entry *e = &rel->array[i];
321  e->buf = alloc_buf(buf_size);
322  ASSERT(buf_init(&e->buf, offset));
323  }
324 }
325 
326 void
328 {
329  int i;
330  for (i = 0; i < rel->size; ++i)
331  {
332  struct reliable_entry *e = &rel->array[i];
333  free_buf(&e->buf);
334  }
335 }
336 
337 /* no active buffers? */
338 bool
339 reliable_empty(const struct reliable *rel)
340 {
341  int i;
342  for (i = 0; i < rel->size; ++i)
343  {
344  const struct reliable_entry *e = &rel->array[i];
345  if (e->active)
346  {
347  return false;
348  }
349  }
350  return true;
351 }
352 
353 /* del acknowledged items from send buf */
354 void
355 reliable_send_purge(struct reliable *rel, const struct reliable_ack *ack)
356 {
357  int i, j;
358  for (i = 0; i < ack->len; ++i)
359  {
360  packet_id_type pid = ack->packet_id[i];
361  for (j = 0; j < rel->size; ++j)
362  {
363  struct reliable_entry *e = &rel->array[j];
364  if (e->active && e->packet_id == pid)
365  {
367  "ACK received for pid " packet_id_format ", deleting from send buffer",
368  (packet_id_print_type)pid);
369 #if 0
370  /* DEBUGGING -- how close were we timing out on ACK failure and resending? */
371  {
372  if (e->next_try)
373  {
374  const interval_t wake = e->next_try - now;
375  msg(M_INFO, "ACK " packet_id_format ", wake=%d", pid, wake);
376  }
377  }
378 #endif
379  e->active = false;
380  break;
381  }
382  }
383  }
384 }
385 
386 /* print the current sequence of active packet IDs */
387 static const char *
388 reliable_print_ids(const struct reliable *rel, struct gc_arena *gc)
389 {
390  struct buffer out = alloc_buf_gc(256, gc);
391  int i;
392 
394  for (i = 0; i < rel->size; ++i)
395  {
396  const struct reliable_entry *e = &rel->array[i];
397  if (e->active)
398  {
400  }
401  }
402  return BSTR(&out);
403 }
404 
405 /* true if at least one free buffer available */
406 bool
407 reliable_can_get(const struct reliable *rel)
408 {
409  struct gc_arena gc = gc_new();
410  int i;
411  for (i = 0; i < rel->size; ++i)
412  {
413  const struct reliable_entry *e = &rel->array[i];
414  if (!e->active)
415  {
416  return true;
417  }
418  }
419  dmsg(D_REL_LOW, "ACK no free receive buffer available: %s", reliable_print_ids(rel, &gc));
420  gc_free(&gc);
421  return false;
422 }
423 
424 /* make sure that incoming packet ID isn't a replay */
425 bool
427 {
428  struct gc_arena gc = gc_new();
429  int i;
430  if (reliable_pid_min(id, rel->packet_id))
431  {
432  goto bad;
433  }
434  for (i = 0; i < rel->size; ++i)
435  {
436  const struct reliable_entry *e = &rel->array[i];
437  if (e->active && e->packet_id == id)
438  {
439  goto bad;
440  }
441  }
442  gc_free(&gc);
443  return true;
444 
445 bad:
446  dmsg(D_REL_DEBUG, "ACK " packet_id_format " is a replay: %s", (packet_id_print_type)id, reliable_print_ids(rel, &gc));
447  gc_free(&gc);
448  return false;
449 }
450 
451 /* make sure that incoming packet ID won't deadlock the receive buffer */
452 bool
454 {
455  struct gc_arena gc = gc_new();
456 
457  const int ret = reliable_pid_in_range2(id, rel->packet_id, rel->size);
458 
459  if (!ret)
460  {
461  dmsg(D_REL_LOW, "ACK " packet_id_format " breaks sequentiality: %s",
463  }
464 
465  dmsg(D_REL_DEBUG, "ACK RWBS rel->size=%d rel->packet_id=%08x id=%08x ret=%d", rel->size, rel->packet_id, id, ret);
466 
467  gc_free(&gc);
468  return ret;
469 }
470 
471 /* grab a free buffer */
472 struct buffer *
474 {
475  int i;
476  for (i = 0; i < rel->size; ++i)
477  {
478  struct reliable_entry *e = &rel->array[i];
479  if (!e->active)
480  {
481  ASSERT(buf_init(&e->buf, rel->offset));
482  return &e->buf;
483  }
484  }
485  return NULL;
486 }
487 
488 /* grab a free buffer, fail if buffer clogged by unacknowledged low packet IDs */
489 struct buffer *
491 {
492  struct gc_arena gc = gc_new();
493  int i;
494  packet_id_type min_id = 0;
495  bool min_id_defined = false;
496  struct buffer *ret = NULL;
497 
498  /* find minimum active packet_id */
499  for (i = 0; i < rel->size; ++i)
500  {
501  const struct reliable_entry *e = &rel->array[i];
502  if (e->active)
503  {
504  if (!min_id_defined || reliable_pid_min(e->packet_id, min_id))
505  {
506  min_id_defined = true;
507  min_id = e->packet_id;
508  }
509  }
510  }
511 
512  if (!min_id_defined || reliable_pid_in_range1(rel->packet_id, min_id, rel->size))
513  {
514  ret = reliable_get_buf(rel);
515  }
516  else
517  {
518  dmsg(D_REL_LOW, "ACK output sequence broken: %s", reliable_print_ids(rel, &gc));
519  }
520  gc_free(&gc);
521  return ret;
522 }
523 
524 /* get active buffer for next sequentially increasing key ID */
525 struct buffer *
527 {
528  int i;
529  for (i = 0; i < rel->size; ++i)
530  {
531  struct reliable_entry *e = &rel->array[i];
532  if (e->active && e->packet_id == rel->packet_id)
533  {
534  return &e->buf;
535  }
536  }
537  return NULL;
538 }
539 
540 /* return true if reliable_send would return a non-NULL result */
541 bool
542 reliable_can_send(const struct reliable *rel)
543 {
544  struct gc_arena gc = gc_new();
545  int i;
546  int n_active = 0, n_current = 0;
547  for (i = 0; i < rel->size; ++i)
548  {
549  const struct reliable_entry *e = &rel->array[i];
550  if (e->active)
551  {
552  ++n_active;
553  if (now >= e->next_try)
554  {
555  ++n_current;
556  }
557  }
558  }
559  dmsg(D_REL_DEBUG, "ACK reliable_can_send active=%d current=%d : %s",
560  n_active,
561  n_current,
562  reliable_print_ids(rel, &gc));
563 
564  gc_free(&gc);
565  return n_current > 0 && !rel->hold;
566 }
567 
568 /* return next buffer to send to remote */
569 struct buffer *
570 reliable_send(struct reliable *rel, int *opcode)
571 {
572  int i;
573  struct reliable_entry *best = NULL;
574  const time_t local_now = now;
575 
576  for (i = 0; i < rel->size; ++i)
577  {
578  struct reliable_entry *e = &rel->array[i];
579  if (e->active && local_now >= e->next_try)
580  {
581  if (!best || reliable_pid_min(e->packet_id, best->packet_id))
582  {
583  best = e;
584  }
585  }
586  }
587  if (best)
588  {
589 #ifdef EXPONENTIAL_BACKOFF
590  /* exponential backoff */
591  best->next_try = local_now + best->timeout;
592  best->timeout *= 2;
593 #else
594  /* constant timeout, no backoff */
595  best->next_try = local_now + best->timeout;
596 #endif
597  *opcode = best->opcode;
598  dmsg(D_REL_DEBUG, "ACK reliable_send ID " packet_id_format " (size=%d to=%d)",
599  (packet_id_print_type)best->packet_id, best->buf.len,
600  (int)(best->next_try - local_now));
601  return &best->buf;
602  }
603  return NULL;
604 }
605 
606 /* schedule all pending packets for immediate retransmit */
607 void
609 {
610  int i;
611  dmsg(D_REL_DEBUG, "ACK reliable_schedule_now");
612  rel->hold = false;
613  for (i = 0; i < rel->size; ++i)
614  {
615  struct reliable_entry *e = &rel->array[i];
616  if (e->active)
617  {
618  e->next_try = now;
619  e->timeout = rel->initial_timeout;
620  }
621  }
622 }
623 
624 /* in how many seconds should we wake up to check for timeout */
625 /* if we return BIG_TIMEOUT, nothing to wait for */
627 reliable_send_timeout(const struct reliable *rel)
628 {
629  struct gc_arena gc = gc_new();
630  interval_t ret = BIG_TIMEOUT;
631  int i;
632  const time_t local_now = now;
633 
634  for (i = 0; i < rel->size; ++i)
635  {
636  const struct reliable_entry *e = &rel->array[i];
637  if (e->active)
638  {
639  if (e->next_try <= local_now)
640  {
641  ret = 0;
642  break;
643  }
644  else
645  {
646  ret = min_int(ret, e->next_try - local_now);
647  }
648  }
649  }
650 
651  dmsg(D_REL_DEBUG, "ACK reliable_send_timeout %d %s",
652  (int) ret,
653  reliable_print_ids(rel, &gc));
654 
655  gc_free(&gc);
656  return ret;
657 }
658 
659 /*
660  * Enable an incoming buffer previously returned by a get function as active.
661  */
662 
663 void
665  packet_id_type pid, int opcode)
666 {
667  int i;
668  for (i = 0; i < rel->size; ++i)
669  {
670  struct reliable_entry *e = &rel->array[i];
671  if (buf == &e->buf)
672  {
673  e->active = true;
674 
675  /* packets may not arrive in sequential order */
676  e->packet_id = pid;
677 
678  /* check for replay */
679  ASSERT(!reliable_pid_min(pid, rel->packet_id));
680 
681  e->opcode = opcode;
682  e->next_try = 0;
683  e->timeout = 0;
684  dmsg(D_REL_DEBUG, "ACK mark active incoming ID " packet_id_format, (packet_id_print_type)e->packet_id);
685  return;
686  }
687  }
688  ASSERT(0); /* buf not found in rel */
689 }
690 
691 /*
692  * Enable an outgoing buffer previously returned by a get function as active.
693  */
694 
695 void
697 {
698  int i;
699  for (i = 0; i < rel->size; ++i)
700  {
701  struct reliable_entry *e = &rel->array[i];
702  if (buf == &e->buf)
703  {
704  /* Write mode, increment packet_id (i.e. sequence number)
705  * linearly and prepend id to packet */
706  packet_id_type net_pid;
707  e->packet_id = rel->packet_id++;
708  net_pid = htonpid(e->packet_id);
709  ASSERT(buf_write_prepend(buf, &net_pid, sizeof(net_pid)));
710  e->active = true;
711  e->opcode = opcode;
712  e->next_try = 0;
713  e->timeout = rel->initial_timeout;
714  dmsg(D_REL_DEBUG, "ACK mark active outgoing ID " packet_id_format, (packet_id_print_type)e->packet_id);
715  return;
716  }
717  }
718  ASSERT(0); /* buf not found in rel */
719 }
720 
721 /* delete a buffer previously activated by reliable_mark_active() */
722 void
723 reliable_mark_deleted(struct reliable *rel, struct buffer *buf, bool inc_pid)
724 {
725  int i;
726  for (i = 0; i < rel->size; ++i)
727  {
728  struct reliable_entry *e = &rel->array[i];
729  if (buf == &e->buf)
730  {
731  e->active = false;
732  if (inc_pid)
733  {
734  rel->packet_id = e->packet_id + 1;
735  }
736  return;
737  }
738  }
739  ASSERT(0);
740 }
741 
742 #if 0
743 
744 void
745 reliable_ack_debug_print(const struct reliable_ack *ack, char *desc)
746 {
747  int i;
748 
749  printf("********* struct reliable_ack %s\n", desc);
750  for (i = 0; i < ack->len; ++i)
751  {
752  printf(" %d: " packet_id_format "\n", i, (packet_id_print_type) ack->packet_id[i]);
753  }
754 }
755 
756 void
757 reliable_debug_print(const struct reliable *rel, char *desc)
758 {
759  int i;
760  update_time();
761 
762  printf("********* struct reliable %s\n", desc);
763  printf(" initial_timeout=%d\n", (int)rel->initial_timeout);
764  printf(" packet_id=" packet_id_format "\n", rel->packet_id);
765  printf(" now=%"PRIi64"\n", (int64_t)now);
766  for (i = 0; i < rel->size; ++i)
767  {
768  const struct reliable_entry *e = &rel->array[i];
769  if (e->active)
770  {
771  printf(" %d: packet_id=" packet_id_format " len=%d", i, e->packet_id, e->buf.len);
772  printf(" next_try=%"PRIi64, (int64_t)e->next_try);
773  printf("\n");
774  }
775  }
776 }
777 
778 #endif /* if 0 */
void reliable_free(struct reliable *rel)
Free allocated memory associated with a reliable structure.
Definition: reliable.c:327
struct reliable_entry array[RELIABLE_CAPACITY]
Definition: reliable.h:95
#define BIG_TIMEOUT
Definition: common.h:50
interval_t initial_timeout
Definition: reliable.h:91
void free_buf(struct buffer *buf)
Definition: buffer.c:183
static bool session_id_equal(const struct session_id *sid1, const struct session_id *sid2)
Definition: session_id.h:48
static bool session_id_write(const struct session_id *sid, struct buffer *buf)
Definition: session_id.h:73
int offset
Definition: reliable.h:93
#define M_INFO
Definition: errlevel.h:55
Packet geometry parameters.
Definition: mtu.h:93
#define RELIABLE_ACK_SIZE
The maximum number of packet IDs waiting to be acknowledged which can be stored in one reliable_ack s...
Definition: reliable.h:46
static void gc_free(struct gc_arena *a)
Definition: buffer.h:999
int opcode
Definition: reliable.h:80
#define ASSERT(x)
Definition: error.h:221
struct buffer alloc_buf(size_t size)
Definition: buffer.c:62
void reliable_debug_print(const struct reliable *rel, char *desc)
#define packet_id_format
Definition: packet_id.h:95
bool reliable_empty(const struct reliable *rel)
Check whether a reliable structure is empty.
Definition: reliable.c:339
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:243
#define CLEAR(x)
Definition: basic.h:33
struct buffer * reliable_get_buf(struct reliable *rel)
Get the buffer of a free reliable entry in which to store a packet.
Definition: reliable.c:473
packet_id_type packet_id[RELIABLE_ACK_SIZE]
Definition: reliable.h:67
static void frame_add_to_extra_frame(struct frame *frame, const int increment)
Definition: mtu.h:274
static bool buf_read(struct buffer *src, void *dest, int size)
Definition: buffer.h:783
int offset
Offset in bytes of the actual content within the allocated memory.
Definition: buffer.h:64
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.
Definition: reliable.c:696
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
static bool buf_write(struct buffer *dest, const void *src, int size)
Definition: buffer.h:672
static bool reliable_pid_in_range1(const packet_id_type test, const packet_id_type base, const unsigned int extent)
Definition: reliable.c:48
bool reliable_ack_write(struct reliable_ack *ack, struct buffer *buf, const struct session_id *sid, int max, bool prepend)
Write a packet ID acknowledgment record to a buffer.
Definition: reliable.c:213
static bool reliable_ack_packet_id_present(struct reliable_ack *ack, packet_id_type pid)
Definition: reliable.c:108
packet_id_type packet_id
Definition: reliable.h:92
Reliability Layer module header file.
unsigned int packet_id_print_type
Definition: packet_id.h:96
static struct gc_arena gc_new(void)
Definition: buffer.h:991
time_t now
Definition: otime.c:36
void reliable_ack_adjust_frame_parameters(struct frame *frame, int max)
Definition: reliable.c:258
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Definition: buffer.c:224
static bool reliable_pid_in_range2(const packet_id_type test, const packet_id_type base, const unsigned int extent)
Definition: reliable.c:74
bool reliable_not_replay(const struct reliable *rel, packet_id_type id)
Check that a received packet&#39;s ID is not a replay.
Definition: reliable.c:426
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...
Definition: reliable.c:490
#define ntohpid(x)
Definition: packet_id.h:64
const char * reliable_ack_print(struct buffer *buf, bool verbose, struct gc_arena *gc)
Definition: reliable.c:265
bool active
Definition: reliable.h:76
interval_t reliable_send_timeout(const struct reliable *rel)
Determined how many seconds until the earliest resend should be attempted.
Definition: reliable.c:627
#define D_REL_DEBUG
Definition: errlevel.h:156
struct buffer buf
Definition: reliable.h:81
static bool session_id_defined(const struct session_id *sid1)
Definition: session_id.h:55
packet_id_type packet_id
Definition: reliable.h:79
static const char * reliable_print_ids(const struct reliable *rel, struct gc_arena *gc)
Definition: reliable.c:388
static bool session_id_read(struct session_id *sid, struct buffer *buf)
Definition: session_id.h:61
#define D_REL_LOW
Definition: errlevel.h:119
#define ACK_SIZE(n)
Definition: reliable.c:208
void reliable_ack_debug_print(const struct reliable_ack *ack, char *desc)
#define dmsg
Definition: error.h:174
#define RELIABLE_CAPACITY
The maximum number of packets that the reliability layer for one VPN tunnel in one direction can stor...
Definition: reliable.h:54
static bool reliable_pid_min(const packet_id_type p1, const packet_id_type p2)
Definition: reliable.c:100
bool hold
Definition: reliable.h:94
bool reliable_wont_break_sequentiality(const struct reliable *rel, packet_id_type id)
Check that a received packet&#39;s ID can safely be stored in the reliable structure&#39;s processing window...
Definition: reliable.c:453
struct buffer * reliable_get_buf_sequenced(struct reliable *rel)
Get the buffer of the next sequential and active entry.
Definition: reliable.c:526
time_t next_try
Definition: reliable.h:78
__int64 int64_t
Definition: config-msvc.h:123
unsigned __int8 uint8_t
Definition: config-msvc.h:122
struct buffer * reliable_send(struct reliable *rel, int *opcode)
Get the next packet to send to the remote peer.
Definition: reliable.c:570
void reliable_mark_deleted(struct reliable *rel, struct buffer *buf, bool inc_pid)
Remove an entry from a reliable structure.
Definition: reliable.c:723
The structure in which the reliability layer stores a single incoming or outgoing packet...
Definition: reliable.h:74
#define msg
Definition: error.h:173
#define htonpid(x)
Definition: packet_id.h:61
The acknowledgment structure in which packet IDs are stored for later acknowledgment.
Definition: reliable.h:64
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
bool reliable_ack_read_packet_id(struct buffer *buf, packet_id_type *pid)
Read the packet ID of a received packet.
Definition: reliable.c:123
#define buf_init(buf, offset)
Definition: buffer.h:196
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Definition: buffer.h:684
bool reliable_can_send(const struct reliable *rel)
Check whether a reliable structure has any active entries ready to be (re)sent.
Definition: reliable.c:542
void reliable_init(struct reliable *rel, int buf_size, int offset, int array_size, bool hold)
Initialize a reliable structure.
Definition: reliable.c:309
The reliability layer storage structure for one VPN tunnel&#39;s control channel in one direction...
Definition: reliable.h:88
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
uint32_t packet_id_type
Definition: packet_id.h:49
static int min_int(int x, int y)
Definition: integer.h:47
bool reliable_can_get(const struct reliable *rel)
Check whether a reliable structure has any free buffers available for use.
Definition: reliable.c:407
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
bool reliable_ack_read(struct reliable_ack *ack, struct buffer *buf, const struct session_id *sid)
Read an acknowledgment record from a received packet.
Definition: reliable.c:158
int interval_t
Definition: common.h:45
const char * session_id_print(const struct session_id *sid, struct gc_arena *gc)
Definition: session_id.c:57
#define BSTR(buf)
Definition: buffer.h:129
int size
Definition: reliable.h:90
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.
Definition: reliable.c:664
static void update_time(void)
Definition: otime.h:93
interval_t timeout
Definition: reliable.h:77
void reliable_schedule_now(struct reliable *rel)
Reschedule all entries of a reliable structure to be ready for (re)sending immediately.
Definition: reliable.c:608
void reliable_send_purge(struct reliable *rel, const struct reliable_ack *ack)
Remove acknowledged packets from a reliable structure.
Definition: reliable.c:355
#define BDEF(buf)
Definition: buffer.h:128
bool reliable_ack_acknowledge_packet_id(struct reliable_ack *ack, packet_id_type pid)
Record a packet ID for later acknowledgment.
Definition: reliable.c:141