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