OpenVPN
packet_id.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/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-2024 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 are designed to catch replay attacks,
26  * where a man-in-the-middle captures packets and then
27  * attempts to replay them back later.
28  *
29  * We use the "sliding-window" algorithm, similar
30  * to IPSec.
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36 
37 #include "syshead.h"
38 
39 #include "packet_id.h"
40 #include "misc.h"
41 #include "integer.h"
42 
43 #include "memdbg.h"
44 
45 /* #define PID_SIMULATE_BACKTRACK */
46 
47 /*
48  * Special time_t value that indicates that
49  * sequence number has expired.
50  */
51 #define SEQ_UNSEEN ((time_t)0)
52 #define SEQ_EXPIRED ((time_t)1)
53 
54 #ifdef ENABLE_DEBUG
55 static void packet_id_debug_print(int msglevel,
56  const struct packet_id_rec *p,
57  const struct packet_id_net *pin,
58  const char *message,
59  int value);
60 
61 #endif /* ENABLE_DEBUG */
62 
63 static inline void
64 packet_id_debug(int msglevel,
65  const struct packet_id_rec *p,
66  const struct packet_id_net *pin,
67  const char *message,
68  int value)
69 {
70 #ifdef ENABLE_DEBUG
71  if (unlikely(check_debug_level(msglevel)))
72  {
73  packet_id_debug_print(msglevel, p, pin, message, value);
74  }
75 #endif
76 }
77 
78 void
79 packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
80 {
81  dmsg(D_PID_DEBUG, "PID packet_id_init seq_backtrack=%d time_backtrack=%d",
82  seq_backtrack,
83  time_backtrack);
84 
85  ASSERT(p);
86  CLEAR(*p);
87 
88  p->rec.name = name;
89  p->rec.unit = unit;
90  if (seq_backtrack)
91  {
92  ASSERT(MIN_SEQ_BACKTRACK <= seq_backtrack && seq_backtrack <= MAX_SEQ_BACKTRACK);
93  ASSERT(MIN_TIME_BACKTRACK <= time_backtrack && time_backtrack <= MAX_TIME_BACKTRACK);
94  CIRC_LIST_ALLOC(p->rec.seq_list, struct seq_list, seq_backtrack);
95  p->rec.seq_backtrack = seq_backtrack;
96  p->rec.time_backtrack = time_backtrack;
97  }
98  p->rec.initialized = true;
99 }
100 
101 void
103 {
104  if (p)
105  {
106  dmsg(D_PID_DEBUG, "PID packet_id_free");
107  free(p->rec.seq_list);
108  CLEAR(*p);
109  }
110 }
111 
112 void
113 packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
114 {
115  const time_t local_now = now;
116  if (p->seq_list)
117  {
118  packet_id_type diff;
119 
120  /*
121  * If time value increases, start a new
122  * sequence number sequence.
123  */
124  if (!CIRC_LIST_SIZE(p->seq_list)
125  || pin->time > p->time
126  || (pin->id >= (packet_id_type)p->seq_backtrack
127  && pin->id - (packet_id_type)p->seq_backtrack > p->id))
128  {
129  p->time = pin->time;
130  p->id = 0;
131  if (pin->id > (packet_id_type)p->seq_backtrack)
132  {
133  p->id = pin->id - (packet_id_type)p->seq_backtrack;
134  }
136  }
137 
138  while (p->id < pin->id
139 #ifdef PID_SIMULATE_BACKTRACK
140  || (get_random() % 64) < 31
141 #endif
142  )
143  {
145  ++p->id;
146  }
147 
148  diff = p->id - pin->id;
149  if (diff < (packet_id_type) CIRC_LIST_SIZE(p->seq_list)
150  && local_now > SEQ_EXPIRED)
151  {
152  CIRC_LIST_ITEM(p->seq_list, diff) = local_now;
153  }
154  }
155  else
156  {
157  p->time = pin->time;
158  p->id = pin->id;
159  }
160 }
161 
162 /*
163  * Expire sequence numbers which can no longer
164  * be accepted because they would violate
165  * time_backtrack.
166  */
167 void
169 {
170  const time_t local_now = now;
171  if (p->time_backtrack)
172  {
173  int i;
174  bool expire = false;
175  for (i = 0; i < CIRC_LIST_SIZE(p->seq_list); ++i)
176  {
177  const time_t t = CIRC_LIST_ITEM(p->seq_list, i);
178  if (t == SEQ_EXPIRED)
179  {
180  break;
181  }
182  if (!expire && t && t + p->time_backtrack < local_now)
183  {
184  expire = true;
185  }
186  if (expire)
187  {
189  }
190  }
191  }
192  p->last_reap = local_now;
193 }
194 
195 /*
196  * Return true if packet id is ok, or false if
197  * it is a replay.
198  */
199 bool
201  const struct packet_id_net *pin)
202 {
203  packet_id_type diff;
204 
205  packet_id_debug(D_PID_DEBUG, p, pin, "PID_TEST", 0);
206 
207  ASSERT(p->initialized);
208 
209  if (!pin->id)
210  {
211  return false;
212  }
213 
214  if (p->seq_backtrack)
215  {
216  /*
217  * In backtrack mode, we allow packet reordering subject
218  * to the seq_backtrack and time_backtrack constraints.
219  *
220  * This mode is used with UDP.
221  */
222  if (pin->time == p->time)
223  {
224  /* is packet-id greater than any one we've seen yet? */
225  if (pin->id > p->id)
226  {
227  return true;
228  }
229 
230  /* check packet-id sliding window for original/replay status */
231  diff = p->id - pin->id;
232 
233  /* keep track of maximum backtrack seen for debugging purposes */
234  if ((int)diff > p->max_backtrack_stat)
235  {
236  p->max_backtrack_stat = (int)diff;
237  packet_id_debug(D_PID_DEBUG_LOW, p, pin, "PID_ERR replay-window backtrack occurred", p->max_backtrack_stat);
238  }
239 
240  if (diff >= (packet_id_type) CIRC_LIST_SIZE(p->seq_list))
241  {
242  packet_id_debug(D_PID_DEBUG_LOW, p, pin, "PID_ERR large diff", diff);
243  return false;
244  }
245 
246  {
247  const time_t v = CIRC_LIST_ITEM(p->seq_list, diff);
248  if (v == 0)
249  {
250  return true;
251  }
252  else
253  {
254  /* raised from D_PID_DEBUG_LOW to reduce verbosity */
255  packet_id_debug(D_PID_DEBUG_MEDIUM, p, pin, "PID_ERR replay", diff);
256  return false;
257  }
258  }
259  }
260  else if (pin->time < p->time) /* if time goes back, reject */
261  {
262  packet_id_debug(D_PID_DEBUG_LOW, p, pin, "PID_ERR time backtrack", 0);
263  return false;
264  }
265  else /* time moved forward */
266  {
267  return true;
268  }
269  }
270  else
271  {
272  /*
273  * In non-backtrack mode, all sequence number series must
274  * begin at some number n > 0 and must increment linearly without gaps.
275  *
276  * This mode is used with TCP.
277  */
278  if (pin->time == p->time)
279  {
280  return !p->id || pin->id == p->id + 1;
281  }
282  else if (pin->time < p->time) /* if time goes back, reject */
283  {
284  return false;
285  }
286  else /* time moved forward */
287  {
288  return pin->id == 1;
289  }
290  }
291 }
292 
293 /*
294  * Read/write a packet ID to/from the buffer. Short form is sequence number
295  * only. Long form is sequence number and timestamp.
296  */
297 
298 bool
299 packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
300 {
301  packet_id_type net_id;
302  net_time_t net_time;
303 
304  pin->id = 0;
305  pin->time = 0;
306 
307  if (!buf_read(buf, &net_id, sizeof(net_id)))
308  {
309  return false;
310  }
311  pin->id = ntohpid(net_id);
312  if (long_form)
313  {
314  if (!buf_read(buf, &net_time, sizeof(net_time)))
315  {
316  return false;
317  }
318  pin->time = ntohtime(net_time);
319  }
320  return true;
321 }
322 
323 static bool
324 packet_id_send_update(struct packet_id_send *p, bool long_form)
325 {
326  if (!p->time)
327  {
328  p->time = now;
329  }
330  if (p->id == PACKET_ID_MAX)
331  {
332  /* Packet ID only allowed to roll over if using long form and time has
333  * moved forward since last roll over.
334  */
335  if (!long_form || now <= p->time)
336  {
337  return false;
338  }
339  p->time = now;
340  p->id = 0;
341  }
342  p->id++;
343  return true;
344 }
345 
346 bool
347 packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form,
348  bool prepend)
349 {
350  if (!packet_id_send_update(p, long_form))
351  {
352  return false;
353  }
354 
355  const packet_id_type net_id = htonpid(p->id);
356  const net_time_t net_time = htontime(p->time);
357  if (prepend)
358  {
359  if (long_form)
360  {
361  if (!buf_write_prepend(buf, &net_time, sizeof(net_time)))
362  {
363  return false;
364  }
365  }
366  if (!buf_write_prepend(buf, &net_id, sizeof(net_id)))
367  {
368  return false;
369  }
370  }
371  else
372  {
373  if (!buf_write(buf, &net_id, sizeof(net_id)))
374  {
375  return false;
376  }
377  if (long_form)
378  {
379  if (!buf_write(buf, &net_time, sizeof(net_time)))
380  {
381  return false;
382  }
383  }
384  }
385  return true;
386 }
387 
388 const char *
389 packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc)
390 {
391  struct buffer out = alloc_buf_gc(256, gc);
392 
394  if (print_timestamp && pin->time)
395  {
396  buf_printf(&out, " / time = (" packet_id_format ") %s",
398  time_string(pin->time, 0, false, gc));
399  }
400 
401  buf_printf(&out, " ]");
402  return BSTR(&out);
403 }
404 
405 /* initialize the packet_id_persist structure in a disabled state */
406 void
408 {
409  p->filename = NULL;
410  p->fd = -1;
411  p->time = p->time_last_written = 0;
412  p->id = p->id_last_written = 0;
413 }
414 
415 /* close the file descriptor if it is open, and switch to disabled state */
416 void
418 {
420  {
421  if (close(p->fd))
422  {
423  msg(D_PID_PERSIST | M_ERRNO, "Close error on --replay-persist file %s", p->filename);
424  }
426  }
427 }
428 
429 /* load persisted rec packet_id (time and id) only once from file, and set state to enabled */
430 void
431 packet_id_persist_load(struct packet_id_persist *p, const char *filename)
432 {
433  struct gc_arena gc = gc_new();
435  {
436  /* open packet-id persist file for both read and write */
437  p->fd = platform_open(filename,
438  O_CREAT | O_RDWR | O_BINARY,
439  S_IRUSR | S_IWUSR);
440  if (p->fd == -1)
441  {
443  "Cannot open --replay-persist file %s for read/write",
444  filename);
445  }
446  else
447  {
448  struct packet_id_persist_file_image image;
449  ssize_t n;
450 
451 #if defined(HAVE_FLOCK) && defined(LOCK_EX) && defined(LOCK_NB)
452  if (flock(p->fd, LOCK_EX | LOCK_NB))
453  {
454  msg(M_ERR, "Cannot obtain exclusive lock on --replay-persist file %s", filename);
455  }
456 #endif
457 
458  p->filename = filename;
459  n = read(p->fd, &image, sizeof(image));
460  if (n == sizeof(image))
461  {
462  p->time = p->time_last_written = image.time;
463  p->id = p->id_last_written = image.id;
464  dmsg(D_PID_PERSIST_DEBUG, "PID Persist Read from %s: %s",
465  p->filename, packet_id_persist_print(p, &gc));
466  }
467  else if (n == -1)
468  {
470  "Read error on --replay-persist file %s",
471  p->filename);
472  }
473  }
474  }
475  gc_free(&gc);
476 }
477 
478 /* save persisted rec packet_id (time and id) to file (only if enabled state) */
479 void
481 {
482  if (packet_id_persist_enabled(p) && p->time && (p->time != p->time_last_written
483  || p->id != p->id_last_written))
484  {
485  struct packet_id_persist_file_image image;
486  ssize_t n;
487  off_t seek_ret;
488  struct gc_arena gc = gc_new();
489 
490  image.time = p->time;
491  image.id = p->id;
492  seek_ret = lseek(p->fd, (off_t)0, SEEK_SET);
493  if (seek_ret == (off_t)0)
494  {
495  n = write(p->fd, &image, sizeof(image));
496  if (n == sizeof(image))
497  {
498  p->time_last_written = p->time;
499  p->id_last_written = p->id;
500  dmsg(D_PID_PERSIST_DEBUG, "PID Persist Write to %s: %s",
501  p->filename, packet_id_persist_print(p, &gc));
502  }
503  else
504  {
506  "Cannot write to --replay-persist file %s",
507  p->filename);
508  }
509  }
510  else
511  {
513  "Cannot seek to beginning of --replay-persist file %s",
514  p->filename);
515  }
516  gc_free(&gc);
517  }
518 }
519 
520 /* transfer packet_id_persist -> packet_id */
521 void
523 {
524  if (p && pid && packet_id_persist_enabled(p) && p->time)
525  {
526  pid->rec.time = p->time;
527  pid->rec.id = p->id;
528  }
529 }
530 
531 const char *
533 {
534  struct buffer out = alloc_buf_gc(256, gc);
535 
536  buf_printf(&out, "[");
537 
539  {
541  if (p->time)
542  {
543  buf_printf(&out, " / time = (" packet_id_format ") %s",
545  time_string(p->time, 0, false, gc));
546  }
547  }
548 
549  buf_printf(&out, " ]");
550  return (char *)out.data;
551 }
552 
553 #ifdef ENABLE_DEBUG
554 
555 static void
556 packet_id_debug_print(int msglevel,
557  const struct packet_id_rec *p,
558  const struct packet_id_net *pin,
559  const char *message,
560  int value)
561 {
562  struct gc_arena gc = gc_new();
563  struct buffer out = alloc_buf_gc(256, &gc);
564  struct timeval tv;
565  const time_t prev_now = now;
566  const struct seq_list *sl = p->seq_list;
567  int i;
568 
569  CLEAR(tv);
570  gettimeofday(&tv, NULL);
571 
572  buf_printf(&out, "%s [%d]", message, value);
573  buf_printf(&out, " [%s-%d] [", p->name, p->unit);
574  for (i = 0; sl != NULL && i < sl->x_size; ++i)
575  {
576  char c;
577  time_t v;
578  int diff;
579 
580  v = CIRC_LIST_ITEM(sl, i);
581  if (v == SEQ_UNSEEN)
582  {
583  c = '_';
584  }
585  else if (v == SEQ_EXPIRED)
586  {
587  c = 'E';
588  }
589  else
590  {
591  diff = (int) prev_now - v;
592  if (diff < 0)
593  {
594  c = 'N';
595  }
596  else if (diff < 10)
597  {
598  c = '0' + diff;
599  }
600  else
601  {
602  c = '>';
603  }
604  }
605  buf_printf(&out, "%c", c);
606  }
607  buf_printf(&out, "] %" PRIi64 ":" packet_id_format, (int64_t)p->time, (packet_id_print_type)p->id);
608  if (pin)
609  {
610  buf_printf(&out, " %" PRIi64 ":" packet_id_format, (int64_t)pin->time, (packet_id_print_type)pin->id);
611  }
612 
613  buf_printf(&out, " t=%" PRIi64 "[%d]",
614  (int64_t)prev_now,
615  (int)(prev_now - tv.tv_sec));
616 
617  buf_printf(&out, " r=[%d,%d,%d,%d,%d]",
618  (int)(p->last_reap - tv.tv_sec),
619  p->seq_backtrack,
620  p->time_backtrack,
622  (int)p->initialized);
623  if (sl != NULL)
624  {
625  buf_printf(&out, " sl=[%d,%d,%d,%d]",
626  sl->x_head,
627  sl->x_size,
628  sl->x_cap,
629  sl->x_sizeof);
630  }
631 
632 
633  msg(msglevel, "%s", BSTR(&out));
634  gc_free(&gc);
635 }
636 
637 #endif /* ifdef ENABLE_DEBUG */
packet_id_send::id
packet_id_type id
Definition: packet_id.h:167
packet_id_rec::id
packet_id_type id
Definition: packet_id.h:131
buf_read
static bool buf_read(struct buffer *src, void *dest, int size)
Definition: buffer.h:783
packet_id_rec::unit
int unit
Definition: packet_id.h:138
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1030
packet_id_persist::filename
const char * filename
Definition: packet_id.h:147
packet_id_send::time
time_t time
Definition: packet_id.h:168
M_ERRNO
#define M_ERRNO
Definition: error.h:94
packet_id_debug
static void packet_id_debug(int msglevel, const struct packet_id_rec *p, const struct packet_id_net *pin, const char *message, int value)
Definition: packet_id.c:64
packet_id_init
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition: packet_id.c:79
MAX_SEQ_BACKTRACK
#define MAX_SEQ_BACKTRACK
Definition: packet_id.h:99
unlikely
#define unlikely(x)
Definition: syshead.h:36
packet_id_persist_file_image::id
packet_id_type id
Definition: packet_id.h:158
packet_id_persist_load
void packet_id_persist_load(struct packet_id_persist *p, const char *filename)
Definition: packet_id.c:431
packet_id_persist_enabled
static bool packet_id_persist_enabled(const struct packet_id_persist *p)
Definition: packet_id.h:276
SEQ_UNSEEN
#define SEQ_UNSEEN
Definition: packet_id.c:51
ntohtime
#define ntohtime(x)
Definition: packet_id.h:65
packet_id_reap
void packet_id_reap(struct packet_id_rec *p)
Definition: packet_id.c:168
BSTR
#define BSTR(buf)
Definition: buffer.h:129
packet_id::rec
struct packet_id_rec rec
Definition: packet_id.h:203
get_random
long int get_random(void)
Definition: crypto.c:1611
MAX_TIME_BACKTRACK
#define MAX_TIME_BACKTRACK
Definition: packet_id.h:108
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
SEQ_EXPIRED
#define SEQ_EXPIRED
Definition: packet_id.c:52
packet_id_persist_file_image
Definition: packet_id.h:155
dmsg
#define dmsg(flags,...)
Definition: error.h:148
D_PID_DEBUG_MEDIUM
#define D_PID_DEBUG_MEDIUM
Definition: errlevel.h:107
packet_id_test
bool packet_id_test(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition: packet_id.c:200
packet_id_persist_file_image::time
time_t time
Definition: packet_id.h:157
packet_id
Definition: packet_id.h:200
CIRC_LIST_PUSH
#define CIRC_LIST_PUSH(obj, item)
Definition: circ_list.h:40
CLEAR
#define CLEAR(x)
Definition: basic.h:33
packet_id_net::id
packet_id_type id
Definition: packet_id.h:196
packet_id_persist::id
packet_id_type id
Definition: packet_id.h:150
htonpid
#define htonpid(x)
Definition: packet_id.h:56
ASSERT
#define ASSERT(x)
Definition: error.h:195
read
@ read
Definition: interactive.c:218
packet_id_persist_save
void packet_id_persist_save(struct packet_id_persist *p)
Definition: packet_id.c:480
packet_id_send_update
static bool packet_id_send_update(struct packet_id_send *p, bool long_form)
Definition: packet_id.c:324
packet_id.h
write
@ write
Definition: interactive.c:219
packet_id_rec::initialized
bool initialized
Definition: packet_id.h:135
packet_id_rec::max_backtrack_stat
int max_backtrack_stat
Definition: packet_id.h:134
buf_write_prepend
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Definition: buffer.h:685
D_PID_PERSIST
#define D_PID_PERSIST
Definition: errlevel.h:68
packet_id_rec
Definition: packet_id.h:127
misc.h
packet_id_persist_init
void packet_id_persist_init(struct packet_id_persist *p)
Definition: packet_id.c:407
packet_id_persist::time
time_t time
Definition: packet_id.h:149
packet_id_rec::seq_backtrack
int seq_backtrack
Definition: packet_id.h:132
M_ERR
#define M_ERR
Definition: error.h:105
packet_id_read
bool packet_id_read(struct packet_id_net *pin, struct buffer *buf, bool long_form)
Definition: packet_id.c:299
packet_id_type
uint32_t packet_id_type
Definition: packet_id.h:44
CIRC_LIST_ALLOC
#define CIRC_LIST_ALLOC(dest, list_type, size)
Definition: circ_list.h:64
packet_id_net::time
time_t time
Definition: packet_id.h:197
packet_id_add
void packet_id_add(struct packet_id_rec *p, const struct packet_id_net *pin)
Definition: packet_id.c:113
ntohpid
#define ntohpid(x)
Definition: packet_id.h:59
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
packet_id_net_print
const char * packet_id_net_print(const struct packet_id_net *pin, bool print_timestamp, struct gc_arena *gc)
Definition: packet_id.c:389
packet_id_send
Definition: packet_id.h:165
D_PID_DEBUG_LOW
#define D_PID_DEBUG_LOW
Definition: errlevel.h:106
packet_id_rec::name
const char * name
Definition: packet_id.h:137
buf_write
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition: buffer.h:673
syshead.h
packet_id_print_type
unsigned int packet_id_print_type
Definition: packet_id.h:91
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
packet_id_persist::fd
int fd
Definition: packet_id.h:148
packet_id_rec::time_backtrack
int time_backtrack
Definition: packet_id.h:133
packet_id_write
bool packet_id_write(struct packet_id_send *p, struct buffer *buf, bool long_form, bool prepend)
Write a packet ID to buf, and update the packet ID state.
Definition: packet_id.c:347
MIN_TIME_BACKTRACK
#define MIN_TIME_BACKTRACK
Definition: packet_id.h:107
check_debug_level
static bool check_debug_level(unsigned int level)
Definition: error.h:220
O_BINARY
#define O_BINARY
Definition: syshead.h:409
packet_id_persist_print
const char * packet_id_persist_print(const struct packet_id_persist *p, struct gc_arena *gc)
Definition: packet_id.c:532
packet_id_persist
Definition: openvpn.h:81
packet_id_persist::id_last_written
packet_id_type id_last_written
Definition: packet_id.h:152
net_time_t
uint32_t net_time_t
Definition: packet_id.h:46
packet_id_rec::last_reap
time_t last_reap
Definition: packet_id.h:129
packet_id_persist_load_obj
void packet_id_persist_load_obj(const struct packet_id_persist *p, struct packet_id *pid)
Definition: packet_id.c:522
PACKET_ID_MAX
#define PACKET_ID_MAX
Definition: packet_id.h:45
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1038
CIRC_LIST_ITEM
#define CIRC_LIST_ITEM(obj, index)
Definition: circ_list.h:55
packet_id_persist::time_last_written
time_t time_last_written
Definition: packet_id.h:151
CIRC_LIST_RESET
#define CIRC_LIST_RESET(obj)
Definition: circ_list.h:58
now
time_t now
Definition: otime.c:34
packet_id_format
#define packet_id_format
Definition: packet_id.h:90
config.h
packet_id_net
Definition: packet_id.h:194
time_string
const char * time_string(time_t t, int usec, bool show_usec, struct gc_arena *gc)
Definition: otime.c:108
htontime
#define htontime(x)
Definition: packet_id.h:62
platform_open
int platform_open(const char *path, int flags, int mode)
Definition: platform.c:527
packet_id_rec::time
time_t time
Definition: packet_id.h:130
MIN_SEQ_BACKTRACK
#define MIN_SEQ_BACKTRACK
Definition: packet_id.h:98
CIRC_LIST_SIZE
#define CIRC_LIST_SIZE(obj)
Definition: circ_list.h:47
memdbg.h
packet_id_free
void packet_id_free(struct packet_id *p)
Definition: packet_id.c:102
packet_id_persist_close
void packet_id_persist_close(struct packet_id_persist *p)
Definition: packet_id.c:417
msg
#define msg(flags,...)
Definition: error.h:144
integer.h
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
D_PID_DEBUG
#define D_PID_DEBUG
Definition: errlevel.h:149
packet_id_rec::seq_list
struct seq_list * seq_list
Definition: packet_id.h:136
buffer::data
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68
D_PID_PERSIST_DEBUG
#define D_PID_PERSIST_DEBUG
Definition: errlevel.h:170