OpenVPN
buffer.h
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-2023 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 #ifndef BUFFER_H
25 #define BUFFER_H
26 
27 #include "basic.h"
28 #include "error.h"
29 
30 #define BUF_SIZE_MAX 1000000
31 
32 /*
33  * Define verify_align function, otherwise
34  * it will be a noop.
35  */
36 /* #define VERIFY_ALIGNMENT */
37 
38 /*
39  * Keep track of source file/line of buf_init calls
40  */
41 #ifdef VERIFY_ALIGNMENT
42 #define BUF_INIT_TRACKING
43 #endif
44 
45 /**************************************************************************/
60 struct buffer
61 {
62  int capacity;
64  int offset;
66  int len;
68  uint8_t *data;
70 #ifdef BUF_INIT_TRACKING
71  const char *debug_file;
72  int debug_line;
73 #endif
74 };
75 
76 
77 /**************************************************************************/
87 struct gc_entry
88 {
89  struct gc_entry *next;
91 };
92 
99 {
101  void (*free_fnc)(void *);
102  void *addr;
103 };
104 
105 
116 struct gc_arena
117 {
118  struct gc_entry *list;
121 };
122 
123 
124 #define BPTR(buf) (buf_bptr(buf))
125 #define BEND(buf) (buf_bend(buf))
126 #define BLAST(buf) (buf_blast(buf))
127 #define BLEN(buf) (buf_len(buf))
128 #define BDEF(buf) (buf_defined(buf))
129 #define BSTR(buf) (buf_str(buf))
130 #define BCAP(buf) (buf_forward_capacity(buf))
131 
132 void buf_clear(struct buffer *buf);
133 
134 void free_buf(struct buffer *buf);
135 
136 bool buf_assign(struct buffer *dest, const struct buffer *src);
137 
138 void string_clear(char *str);
139 
140 int string_array_len(const char **array);
141 
142 size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra);
143 
144 #define PA_BRACKET (1<<0)
145 char *print_argv(const char **p, struct gc_arena *gc, const unsigned int flags);
146 
147 void buf_size_error(const size_t size);
148 
149 /* for dmalloc debugging */
150 
151 #ifdef DMALLOC
152 
153 #define alloc_buf(size) alloc_buf_debug(size, __FILE__, __LINE__)
154 #define alloc_buf_gc(size, gc) alloc_buf_gc_debug(size, gc, __FILE__, __LINE__);
155 #define clone_buf(buf) clone_buf_debug(buf, __FILE__, __LINE__);
156 #define gc_malloc(size, clear, arena) gc_malloc_debug(size, clear, arena, __FILE__, __LINE__)
157 #define string_alloc(str, gc) string_alloc_debug(str, gc, __FILE__, __LINE__)
158 #define string_alloc_buf(str, gc) string_alloc_buf_debug(str, gc, __FILE__, __LINE__)
159 
160 struct buffer alloc_buf_debug(size_t size, const char *file, int line);
161 
162 struct buffer alloc_buf_gc_debug(size_t size, struct gc_arena *gc, const char *file, int line);
163 
164 struct buffer clone_buf_debug(const struct buffer *buf, const char *file, int line);
165 
166 void *gc_malloc_debug(size_t size, bool clear, struct gc_arena *a, const char *file, int line);
167 
168 char *string_alloc_debug(const char *str, struct gc_arena *gc, const char *file, int line);
169 
170 struct buffer string_alloc_buf_debug(const char *str, struct gc_arena *gc, const char *file, int line);
171 
172 #else /* ifdef DMALLOC */
173 
174 struct buffer alloc_buf(size_t size);
175 
176 struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
177 
178 struct buffer clone_buf(const struct buffer *buf);
179 
180 void *gc_malloc(size_t size, bool clear, struct gc_arena *a);
181 
182 char *string_alloc(const char *str, struct gc_arena *gc);
183 
184 struct buffer string_alloc_buf(const char *str, struct gc_arena *gc);
185 
186 #endif /* ifdef DMALLOC */
187 
188 void gc_addspecial(void *addr, void (*free_function)(void *), struct gc_arena *a);
189 
201 void *
202 gc_realloc(void *ptr, size_t size, struct gc_arena *a);
203 
204 #ifdef BUF_INIT_TRACKING
205 #define buf_init(buf, offset) buf_init_debug(buf, offset, __FILE__, __LINE__)
206 bool buf_init_debug(struct buffer *buf, int offset, const char *file, int line);
207 
208 #else
209 #define buf_init(buf, offset) buf_init_dowork(buf, offset)
210 #endif
211 
212 
213 /* inline functions */
214 static inline void
216 {
217  freeaddrinfo((struct addrinfo *) addr);
218 }
219 
221 static inline struct buffer
223 {
224  return (struct buffer) { 0 };
225 }
226 
227 static inline bool
228 buf_defined(const struct buffer *buf)
229 {
230  return buf->data != NULL;
231 }
232 
233 static inline bool
234 buf_valid(const struct buffer *buf)
235 {
236  return likely(buf->data != NULL) && likely(buf->len >= 0);
237 }
238 
239 static inline uint8_t *
240 buf_bptr(const struct buffer *buf)
241 {
242  if (buf_valid(buf))
243  {
244  return buf->data + buf->offset;
245  }
246  else
247  {
248  return NULL;
249  }
250 }
251 
252 static int
253 buf_len(const struct buffer *buf)
254 {
255  if (buf_valid(buf))
256  {
257  return buf->len;
258  }
259  else
260  {
261  return 0;
262  }
263 }
264 
265 static inline uint8_t *
266 buf_bend(const struct buffer *buf)
267 {
268  return buf_bptr(buf) + buf_len(buf);
269 }
270 
271 static inline uint8_t *
272 buf_blast(const struct buffer *buf)
273 {
274  if (buf_len(buf) > 0)
275  {
276  return buf_bptr(buf) + buf_len(buf) - 1;
277  }
278  else
279  {
280  return NULL;
281  }
282 }
283 
284 static inline bool
285 buf_size_valid(const size_t size)
286 {
287  return likely(size < BUF_SIZE_MAX);
288 }
289 
290 static inline bool
291 buf_size_valid_signed(const int size)
292 {
293  return likely(size >= -BUF_SIZE_MAX) && likely(size < BUF_SIZE_MAX);
294 }
295 
296 static inline char *
297 buf_str(const struct buffer *buf)
298 {
299  return (char *)buf_bptr(buf);
300 }
301 
302 static inline void
303 buf_reset(struct buffer *buf)
304 {
305  buf->capacity = 0;
306  buf->offset = 0;
307  buf->len = 0;
308  buf->data = NULL;
309 }
310 
311 static inline void
312 buf_reset_len(struct buffer *buf)
313 {
314  buf->len = 0;
315  buf->offset = 0;
316 }
317 
318 static inline bool
319 buf_init_dowork(struct buffer *buf, int offset)
320 {
321  if (offset < 0 || offset > buf->capacity || buf->data == NULL)
322  {
323  return false;
324  }
325  buf->len = 0;
326  buf->offset = offset;
327  return true;
328 }
329 
330 static inline void
331 buf_set_write(struct buffer *buf, uint8_t *data, int size)
332 {
333  if (!buf_size_valid(size))
334  {
335  buf_size_error(size);
336  }
337  buf->len = 0;
338  buf->offset = 0;
339  buf->capacity = size;
340  buf->data = data;
341  if (size > 0 && data)
342  {
343  *data = 0;
344  }
345 }
346 
347 static inline void
348 buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
349 {
350  if (!buf_size_valid(size))
351  {
352  buf_size_error(size);
353  }
354  buf->len = buf->capacity = (int)size;
355  buf->offset = 0;
356  buf->data = (uint8_t *)data;
357 }
358 
359 /* Like strncpy but makes sure dest is always null terminated */
360 static inline void
361 strncpynt(char *dest, const char *src, size_t maxlen)
362 {
363  if (maxlen > 0)
364  {
365  strncpy(dest, src, maxlen-1);
366  dest[maxlen - 1] = 0;
367  }
368 }
369 
370 /* return true if string contains at least one numerical digit */
371 static inline bool
372 has_digit(const char *src)
373 {
374  char c;
375  while ((c = *src++))
376  {
377  if (isdigit(c))
378  {
379  return true;
380  }
381  }
382  return false;
383 }
384 
413 static inline void
414 secure_memzero(void *data, size_t len)
415 {
416 #if defined(_WIN32)
417  SecureZeroMemory(data, len);
418 #elif defined(__GNUC__) || defined(__clang__)
419  memset(data, 0, len);
420  __asm__ __volatile__ ("" : : "r" (data) : "memory");
421 #else
422  volatile char *p = (volatile char *) data;
423  while (len--)
424  {
425  *p++ = 0;
426  }
427 #endif
428 }
429 
430 /*
431  * printf append to a buffer with overflow check,
432  * due to usage of vsnprintf, it will leave space for
433  * a final null character and thus use only
434  * capacity - 1
435  */
436 bool buf_printf(struct buffer *buf, const char *format, ...)
437 #ifdef __GNUC__
438 #if __USE_MINGW_ANSI_STDIO
439 __attribute__ ((format(gnu_printf, 2, 3)))
440 #else
441 __attribute__ ((format(__printf__, 2, 3)))
442 #endif
443 #endif
444 ;
445 
446 /*
447  * puts append to a buffer with overflow check
448  */
449 bool buf_puts(struct buffer *buf, const char *str);
450 
451 /*
452  * Like snprintf but guarantees null termination for size > 0
453  */
454 bool openvpn_snprintf(char *str, size_t size, const char *format, ...)
455 #ifdef __GNUC__
456 #if __USE_MINGW_ANSI_STDIO
457 __attribute__ ((format(gnu_printf, 3, 4)))
458 #else
459 __attribute__ ((format(__printf__, 3, 4)))
460 #endif
461 #endif
462 ;
463 
464 
465 /*
466  * remove/add trailing characters
467  */
468 
469 void buf_null_terminate(struct buffer *buf);
470 
471 void buf_chomp(struct buffer *buf);
472 
473 void buf_rmtail(struct buffer *buf, uint8_t remove);
474 
475 /*
476  * non-buffer string functions
477  */
478 void chomp(char *str);
479 
480 void rm_trailing_chars(char *str, const char *what_to_delete);
481 
482 const char *skip_leading_whitespace(const char *str);
483 
484 void string_null_terminate(char *str, int len, int capacity);
485 
494 bool buffer_write_file(const char *filename, const struct buffer *buf);
495 
496 /*
497  * write a string to the end of a buffer that was
498  * truncated by buf_printf
499  */
500 void buf_catrunc(struct buffer *buf, const char *str);
501 
502 /*
503  * convert a multi-line output to one line
504  */
505 void convert_to_one_line(struct buffer *buf);
506 
507 /*
508  * Parse a string based on a given delimiter char
509  */
510 bool buf_parse(struct buffer *buf, const int delim, char *line, const int size);
511 
512 /*
513  * Hex dump -- Output a binary buffer to a hex string and return it.
514  */
515 #define FHE_SPACE_BREAK_MASK 0xFF /* space_break parameter in lower 8 bits */
516 #define FHE_CAPS 0x100 /* output hex in caps */
517 char *
518 format_hex_ex(const uint8_t *data, int size, int maxoutput,
519  unsigned int space_break_flags, const char *separator,
520  struct gc_arena *gc);
521 
522 static inline char *
523 format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
524 {
525  return format_hex_ex(data, size, maxoutput, 4, " ", gc);
526 }
527 
528 /*
529  * Return a buffer that is a subset of another buffer.
530  */
531 struct buffer buf_sub(struct buffer *buf, int size, bool prepend);
532 
533 /*
534  * Check if sufficient space to append to buffer.
535  */
536 
537 static inline bool
538 buf_safe(const struct buffer *buf, size_t len)
539 {
540  return buf_valid(buf) && buf_size_valid(len)
541  && buf->offset + buf->len + (int)len <= buf->capacity;
542 }
543 
544 static inline bool
545 buf_safe_bidir(const struct buffer *buf, int len)
546 {
547  if (buf_valid(buf) && buf_size_valid_signed(len))
548  {
549  int newlen = buf->len + len;
550  return newlen >= 0 && buf->offset + newlen <= buf->capacity;
551  }
552  else
553  {
554  return false;
555  }
556 }
557 
558 static inline int
559 buf_forward_capacity(const struct buffer *buf)
560 {
561  if (buf_valid(buf))
562  {
563  int ret = buf->capacity - (buf->offset + buf->len);
564  if (ret < 0)
565  {
566  ret = 0;
567  }
568  return ret;
569  }
570  else
571  {
572  return 0;
573  }
574 }
575 
576 static inline int
578 {
579  if (buf_valid(buf))
580  {
581  int ret = buf->capacity - buf->offset;
582  if (ret < 0)
583  {
584  ret = 0;
585  }
586  return ret;
587  }
588  else
589  {
590  return 0;
591  }
592 }
593 
594 static inline int
595 buf_reverse_capacity(const struct buffer *buf)
596 {
597  if (buf_valid(buf))
598  {
599  return buf->offset;
600  }
601  else
602  {
603  return 0;
604  }
605 }
606 
607 static inline bool
608 buf_inc_len(struct buffer *buf, int inc)
609 {
610  if (!buf_safe_bidir(buf, inc))
611  {
612  return false;
613  }
614  buf->len += inc;
615  return true;
616 }
617 
618 /*
619  * Make space to prepend to a buffer.
620  * Return NULL if no space.
621  */
622 
623 static inline uint8_t *
624 buf_prepend(struct buffer *buf, int size)
625 {
626  if (!buf_valid(buf) || size < 0 || size > buf->offset)
627  {
628  return NULL;
629  }
630  buf->offset -= size;
631  buf->len += size;
632  return BPTR(buf);
633 }
634 
635 static inline bool
636 buf_advance(struct buffer *buf, int size)
637 {
638  if (!buf_valid(buf) || size < 0 || buf->len < size)
639  {
640  return false;
641  }
642  buf->offset += size;
643  buf->len -= size;
644  return true;
645 }
646 
647 /*
648  * Return a pointer to allocated space inside a buffer.
649  * Return NULL if no space.
650  */
651 
652 static inline uint8_t *
653 buf_write_alloc(struct buffer *buf, size_t size)
654 {
655  uint8_t *ret;
656  if (!buf_safe(buf, size))
657  {
658  return NULL;
659  }
660  ret = BPTR(buf) + buf->len;
661  buf->len += (int)size;
662  return ret;
663 }
664 
665 static inline uint8_t *
666 buf_write_alloc_prepend(struct buffer *buf, int size, bool prepend)
667 {
668  return prepend ? buf_prepend(buf, size) : buf_write_alloc(buf, size);
669 }
670 
671 static inline uint8_t *
672 buf_read_alloc(struct buffer *buf, int size)
673 {
674  uint8_t *ret;
675  if (size < 0 || buf->len < size)
676  {
677  return NULL;
678  }
679  ret = BPTR(buf);
680  buf->offset += size;
681  buf->len -= size;
682  return ret;
683 }
684 
685 static inline bool
686 buf_write(struct buffer *dest, const void *src, size_t size)
687 {
688  uint8_t *cp = buf_write_alloc(dest, size);
689  if (!cp)
690  {
691  return false;
692  }
693  memcpy(cp, src, size);
694  return true;
695 }
696 
697 static inline bool
698 buf_write_prepend(struct buffer *dest, const void *src, int size)
699 {
700  uint8_t *cp = buf_prepend(dest, size);
701  if (!cp)
702  {
703  return false;
704  }
705  memcpy(cp, src, size);
706  return true;
707 }
708 
709 static inline bool
710 buf_write_u8(struct buffer *dest, uint8_t data)
711 {
712  return buf_write(dest, &data, sizeof(uint8_t));
713 }
714 
715 static inline bool
716 buf_write_u16(struct buffer *dest, uint16_t data)
717 {
718  uint16_t u16 = htons(data);
719  return buf_write(dest, &u16, sizeof(uint16_t));
720 }
721 
722 static inline bool
723 buf_write_u32(struct buffer *dest, uint32_t data)
724 {
725  uint32_t u32 = htonl(data);
726  return buf_write(dest, &u32, sizeof(uint32_t));
727 }
728 
729 static inline bool
730 buf_copy(struct buffer *dest, const struct buffer *src)
731 {
732  return buf_write(dest, BPTR(src), BLEN(src));
733 }
734 
735 static inline bool
736 buf_copy_n(struct buffer *dest, struct buffer *src, int n)
737 {
738  uint8_t *cp = buf_read_alloc(src, n);
739  if (!cp)
740  {
741  return false;
742  }
743  return buf_write(dest, cp, n);
744 }
745 
746 static inline bool
747 buf_copy_range(struct buffer *dest,
748  int dest_index,
749  const struct buffer *src,
750  int src_index,
751  int src_len)
752 {
753  if (src_index < 0
754  || src_len < 0
755  || src_index + src_len > src->len
756  || dest_index < 0
757  || dest->offset + dest_index + src_len > dest->capacity)
758  {
759  return false;
760  }
761  memcpy(dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
762  if (dest_index + src_len > dest->len)
763  {
764  dest->len = dest_index + src_len;
765  }
766  return true;
767 }
768 
769 /* truncate src to len, copy excess data beyond len to dest */
770 static inline bool
771 buf_copy_excess(struct buffer *dest,
772  struct buffer *src,
773  int len)
774 {
775  if (len < 0)
776  {
777  return false;
778  }
779  if (src->len > len)
780  {
781  struct buffer b = *src;
782  src->len = len;
783  if (!buf_advance(&b, len))
784  {
785  return false;
786  }
787  return buf_copy(dest, &b);
788  }
789  else
790  {
791  return true;
792  }
793 }
794 
795 static inline bool
796 buf_read(struct buffer *src, void *dest, int size)
797 {
798  uint8_t *cp = buf_read_alloc(src, size);
799  if (!cp)
800  {
801  return false;
802  }
803  memcpy(dest, cp, size);
804  return true;
805 }
806 
807 static inline int
808 buf_read_u8(struct buffer *buf)
809 {
810  int ret;
811  if (BLEN(buf) < 1)
812  {
813  return -1;
814  }
815  ret = *BPTR(buf);
816  buf_advance(buf, 1);
817  return ret;
818 }
819 
820 static inline int
821 buf_read_u16(struct buffer *buf)
822 {
823  uint16_t ret;
824  if (!buf_read(buf, &ret, sizeof(uint16_t)))
825  {
826  return -1;
827  }
828  return ntohs(ret);
829 }
830 
831 static inline uint32_t
832 buf_read_u32(struct buffer *buf, bool *good)
833 {
834  uint32_t ret;
835  if (!buf_read(buf, &ret, sizeof(uint32_t)))
836  {
837  if (good)
838  {
839  *good = false;
840  }
841  return 0;
842  }
843  else
844  {
845  if (good)
846  {
847  *good = true;
848  }
849  return ntohl(ret);
850  }
851 }
852 
854 static inline bool
855 buf_equal(const struct buffer *a, const struct buffer *b)
856 {
857  return BLEN(a) == BLEN(b) && 0 == memcmp(BPTR(a), BPTR(b), BLEN(a));
858 }
859 
864 static inline bool
865 buf_string_match(const struct buffer *src, const void *match, int size)
866 {
867  if (size != src->len)
868  {
869  return false;
870  }
871  return memcmp(BPTR(src), match, size) == 0;
872 }
873 
878 static inline bool
879 buf_string_match_head(const struct buffer *src, const void *match, int size)
880 {
881  if (size < 0 || size > src->len)
882  {
883  return false;
884  }
885  return memcmp(BPTR(src), match, size) == 0;
886 }
887 
888 bool buf_string_match_head_str(const struct buffer *src, const char *match);
889 
890 bool buf_string_compare_advance(struct buffer *src, const char *match);
891 
892 int buf_substring_len(const struct buffer *buf, int delim);
893 
894 /*
895  * Print a string which might be NULL
896  */
897 const char *np(const char *str);
898 
899 /* character classes */
900 
901 #define CC_ANY (1<<0)
902 #define CC_NULL (1<<1)
904 #define CC_ALNUM (1<<2)
905 #define CC_ALPHA (1<<3)
906 #define CC_ASCII (1<<4)
907 #define CC_CNTRL (1<<5)
908 #define CC_DIGIT (1<<6)
909 #define CC_PRINT (1<<7)
910 #define CC_PUNCT (1<<8)
911 #define CC_SPACE (1<<9)
912 #define CC_XDIGIT (1<<10)
914 #define CC_BLANK (1<<11)
915 #define CC_NEWLINE (1<<12)
916 #define CC_CR (1<<13)
918 #define CC_BACKSLASH (1<<14)
919 #define CC_UNDERBAR (1<<15)
920 #define CC_DASH (1<<16)
921 #define CC_DOT (1<<17)
922 #define CC_COMMA (1<<18)
923 #define CC_COLON (1<<19)
924 #define CC_SLASH (1<<20)
925 #define CC_SINGLE_QUOTE (1<<21)
926 #define CC_DOUBLE_QUOTE (1<<22)
927 #define CC_REVERSE_QUOTE (1<<23)
928 #define CC_AT (1<<24)
929 #define CC_EQUAL (1<<25)
930 #define CC_LESS_THAN (1<<26)
931 #define CC_GREATER_THAN (1<<27)
932 #define CC_PIPE (1<<28)
933 #define CC_QUESTION_MARK (1<<29)
934 #define CC_ASTERISK (1<<30)
936 /* macro classes */
937 #define CC_NAME (CC_ALNUM|CC_UNDERBAR)
938 #define CC_CRLF (CC_CR|CC_NEWLINE)
940 bool char_class(const unsigned char c, const unsigned int flags);
941 
942 bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive);
943 
957 bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
958 
973 const char *string_mod_const(const char *str,
974  const unsigned int inclusive,
975  const unsigned int exclusive,
976  const char replace,
977  struct gc_arena *gc);
978 
979 void string_replace_leading(char *str, const char match, const char replace);
980 
982 static inline bool
983 strprefix(const char *str, const char *prefix)
984 {
985  return 0 == strncmp(str, prefix, strlen(prefix));
986 }
987 
988 
989 /*
990  * Verify that a pointer is correctly aligned
991  */
992 #ifdef VERIFY_ALIGNMENT
993 void valign4(const struct buffer *buf, const char *file, const int line);
994 
995 #define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
996 #else
997 #define verify_align_4(ptr)
998 #endif
999 
1000 /*
1001  * Very basic garbage collection, mostly for routines that return
1002  * char ptrs to malloced strings.
1003  */
1004 
1005 void gc_transfer(struct gc_arena *dest, struct gc_arena *src);
1006 
1007 void x_gc_free(struct gc_arena *a);
1008 
1009 void x_gc_freespecial(struct gc_arena *a);
1010 
1011 static inline bool
1013 {
1014  return a->list != NULL;
1015 }
1016 
1017 static inline void
1018 gc_init(struct gc_arena *a)
1019 {
1020  a->list = NULL;
1021  a->list_special = NULL;
1022 }
1023 
1024 static inline void
1026 {
1027  gc_init(a);
1028 }
1029 
1030 static inline struct gc_arena
1031 gc_new(void)
1032 {
1033  struct gc_arena ret;
1034  gc_init(&ret);
1035  return ret;
1036 }
1037 
1038 static inline void
1039 gc_free(struct gc_arena *a)
1040 {
1041  if (a->list)
1042  {
1043  x_gc_free(a);
1044  }
1045  if (a->list_special)
1046  {
1047  x_gc_freespecial(a);
1048  }
1049 }
1050 
1051 static inline void
1052 gc_reset(struct gc_arena *a)
1053 {
1054  gc_free(a);
1055 }
1056 
1057 /*
1058  * Allocate memory to hold a structure
1059  */
1060 
1061 #define ALLOC_OBJ(dptr, type) \
1062  { \
1063  check_malloc_return((dptr) = (type *) malloc(sizeof(type))); \
1064  }
1065 
1066 #define ALLOC_OBJ_CLEAR(dptr, type) \
1067  { \
1068  ALLOC_OBJ(dptr, type); \
1069  memset((dptr), 0, sizeof(type)); \
1070  }
1071 
1072 #define ALLOC_ARRAY(dptr, type, n) \
1073  { \
1074  check_malloc_return((dptr) = (type *) malloc(array_mult_safe(sizeof(type), (n), 0))); \
1075  }
1076 
1077 #define ALLOC_ARRAY_GC(dptr, type, n, gc) \
1078  { \
1079  (dptr) = (type *) gc_malloc(array_mult_safe(sizeof(type), (n), 0), false, (gc)); \
1080  }
1081 
1082 #define ALLOC_ARRAY_CLEAR(dptr, type, n) \
1083  { \
1084  ALLOC_ARRAY(dptr, type, n); \
1085  memset((dptr), 0, (array_mult_safe(sizeof(type), (n), 0))); \
1086  }
1087 
1088 #define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
1089  { \
1090  (dptr) = (type *) gc_malloc(array_mult_safe(sizeof(type), (n), 0), true, (gc)); \
1091  }
1092 
1093 #define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \
1094  { \
1095  (dptr) = (type *) gc_malloc(array_mult_safe(sizeof(atype), (n), sizeof(type)), true, (gc)); \
1096  }
1097 
1098 #define ALLOC_OBJ_GC(dptr, type, gc) \
1099  { \
1100  (dptr) = (type *) gc_malloc(sizeof(type), false, (gc)); \
1101  }
1102 
1103 #define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
1104  { \
1105  (dptr) = (type *) gc_malloc(sizeof(type), true, (gc)); \
1106  }
1107 
1108 static inline void
1110 {
1111  if (!p)
1112  {
1113  out_of_memory();
1114  }
1115 }
1116 
1117 /*
1118  * Manage lists of buffers
1119  */
1121 {
1122  struct buffer buf;
1124 };
1125 
1127 {
1128  struct buffer_entry *head; /* next item to pop/peek */
1129  struct buffer_entry *tail; /* last item pushed */
1130  int size; /* current number of entries */
1131  int max_size; /* maximum size list should grow to */
1132 };
1133 
1139 struct buffer_list *buffer_list_new(void);
1140 
1146 void buffer_list_free(struct buffer_list *ol);
1147 
1155 bool buffer_list_defined(const struct buffer_list *ol);
1156 
1162 void buffer_list_reset(struct buffer_list *ol);
1163 
1170 void buffer_list_push(struct buffer_list *ol, const char *str);
1171 
1181 struct buffer_entry *buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size);
1182 
1190 struct buffer *buffer_list_peek(struct buffer_list *ol);
1191 
1192 void buffer_list_advance(struct buffer_list *ol, int n);
1193 
1194 void buffer_list_pop(struct buffer_list *ol);
1195 
1205 void buffer_list_aggregate(struct buffer_list *bl, const size_t max);
1206 
1220  const size_t max_len, const char *sep);
1221 
1222 struct buffer_list *buffer_list_file(const char *fn, int max_line_len);
1223 
1234 struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc);
1235 
1236 #endif /* BUFFER_H */
gc_arena::list
struct gc_entry * list
First element of the linked list of gc_entry structures.
Definition: buffer.h:118
buf_safe
static bool buf_safe(const struct buffer *buf, size_t len)
Definition: buffer.h:538
buf_assign
bool buf_assign(struct buffer *dest, const struct buffer *src)
Definition: buffer.c:173
string_array_len
int string_array_len(const char **array)
Definition: buffer.c:747
buf_copy_range
static bool buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index, int src_len)
Definition: buffer.h:747
buf_read
static bool buf_read(struct buffer *src, void *dest, int size)
Definition: buffer.h:796
error.h
buffer_read_from_file
struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc)
buffer_read_from_file - copy the content of a file into a buffer
Definition: buffer.c:1385
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1031
format_hex_ex
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition: buffer.c:527
buf_forward_capacity_total
static int buf_forward_capacity_total(const struct buffer *buf)
Definition: buffer.h:577
buffer::len
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
buf_reset
static void buf_reset(struct buffer *buf)
Definition: buffer.h:303
free_buf
void free_buf(struct buffer *buf)
Definition: buffer.c:183
buf_null_terminate
void buf_null_terminate(struct buffer *buf)
Definition: buffer.c:577
gc_entry::next
struct gc_entry * next
Pointer to the next item in the linked list.
Definition: buffer.h:89
buf_copy_excess
static bool buf_copy_excess(struct buffer *dest, struct buffer *src, int len)
Definition: buffer.h:771
buf_write_u32
static bool buf_write_u32(struct buffer *dest, uint32_t data)
Definition: buffer.h:723
out_of_memory
void out_of_memory(void)
Definition: error.c:460
buf_size_valid
static bool buf_size_valid(const size_t size)
Definition: buffer.h:285
buffer::capacity
int capacity
Size in bytes of memory allocated by malloc().
Definition: buffer.h:62
openvpn_snprintf
bool openvpn_snprintf(char *str, size_t size, const char *format,...)
Definition: buffer.c:294
buf_safe_bidir
static bool buf_safe_bidir(const struct buffer *buf, int len)
Definition: buffer.h:545
buf_bptr
static uint8_t * buf_bptr(const struct buffer *buf)
Definition: buffer.h:240
gc_entry
Garbage collection entry for one dynamically allocated block of memory.
Definition: buffer.h:87
string_alloc
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:693
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
buf_copy
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Definition: buffer.h:730
clear_buf
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition: buffer.h:222
buf_size_error
void buf_size_error(const size_t size)
Definition: buffer.c:53
buffer_list_peek
struct buffer * buffer_list_peek(struct buffer_list *ol)
Retrieve the head buffer.
Definition: buffer.c:1266
buffer_list_aggregate_separator
void buffer_list_aggregate_separator(struct buffer_list *bl, const size_t max_len, const char *sep)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition: buffer.c:1279
gc_reset
static void gc_reset(struct gc_arena *a)
Definition: buffer.h:1052
buf_rmtail
void buf_rmtail(struct buffer *buf, uint8_t remove)
Definition: buffer.c:562
gc_entry_special::free_fnc
void(* free_fnc)(void *)
Definition: buffer.h:101
gc_arena::list_special
struct gc_entry_special * list_special
Definition: buffer.h:120
buf_read_u32
static uint32_t buf_read_u32(struct buffer *buf, bool *good)
Definition: buffer.h:832
buffer_list_file
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Definition: buffer.c:1362
buf_reset_len
static void buf_reset_len(struct buffer *buf)
Definition: buffer.h:312
gc_addspecial
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
Definition: buffer.c:482
clone_buf
struct buffer clone_buf(const struct buffer *buf)
Definition: buffer.c:115
buf_equal
static bool buf_equal(const struct buffer *a, const struct buffer *b)
Return true if buffer contents are equal.
Definition: buffer.h:855
string_mod
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
Definition: buffer.c:1085
print_argv
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
Definition: buffer.c:761
string_clear
void string_clear(char *str)
Definition: buffer.c:735
buf_clear
void buf_clear(struct buffer *buf)
Definition: buffer.c:162
likely
#define likely(x)
Definition: syshead.h:35
secure_memzero
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition: buffer.h:414
buffer_list_new
struct buffer_list * buffer_list_new(void)
Allocate an empty buffer list of capacity max_size.
Definition: buffer.c:1185
buffer_entry::buf
struct buffer buf
Definition: buffer.h:1122
buf_advance
static bool buf_advance(struct buffer *buf, int size)
Definition: buffer.h:636
buf_write_u16
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Definition: buffer.h:716
buf_inc_len
static bool buf_inc_len(struct buffer *buf, int inc)
Definition: buffer.h:608
buf_string_match_head
static bool buf_string_match_head(const struct buffer *src, const void *match, int size)
Compare first size bytes of src buffer contents with match.
Definition: buffer.h:879
BLEN
#define BLEN(buf)
Definition: buffer.h:127
buf_catrunc
void buf_catrunc(struct buffer *buf, const char *str)
Definition: buffer.c:313
buf_chomp
void buf_chomp(struct buffer *buf)
Definition: buffer.c:598
buf_write_prepend
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
Definition: buffer.h:698
buf_write_u8
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition: buffer.h:710
buffer_entry::next
struct buffer_entry * next
Definition: buffer.h:1123
buf_write_alloc_prepend
static uint8_t * buf_write_alloc_prepend(struct buffer *buf, int size, bool prepend)
Definition: buffer.h:666
buf_string_match
static bool buf_string_match(const struct buffer *src, const void *match, int size)
Compare src buffer contents with match.
Definition: buffer.h:865
buf_substring_len
int buf_substring_len(const struct buffer *buf, int delim)
Definition: buffer.c:847
buf_size_valid_signed
static bool buf_size_valid_signed(const int size)
Definition: buffer.h:291
buf_read_u16
static int buf_read_u16(struct buffer *buf)
Definition: buffer.h:821
buf_string_compare_advance
bool buf_string_compare_advance(struct buffer *src, const char *match)
Definition: buffer.c:833
buf_valid
static bool buf_valid(const struct buffer *buf)
Definition: buffer.h:234
gc_detach
static void gc_detach(struct gc_arena *a)
Definition: buffer.h:1025
gc_realloc
void * gc_realloc(void *ptr, size_t size, struct gc_arena *a)
allows to realloc a pointer previously allocated by gc_malloc or gc_realloc
Definition: buffer.c:414
x_gc_freespecial
void x_gc_freespecial(struct gc_arena *a)
Definition: buffer.c:466
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
buffer_list::size
int size
Definition: buffer.h:1130
gc_defined
static bool gc_defined(struct gc_arena *a)
Definition: buffer.h:1012
string_null_terminate
void string_null_terminate(char *str, int len, int capacity)
Definition: buffer.c:641
buf_string_match_head_str
bool buf_string_match_head_str(const struct buffer *src, const char *match)
Definition: buffer.c:822
chomp
void chomp(char *str)
Definition: buffer.c:658
buffer_list_push
void buffer_list_push(struct buffer_list *ol, const char *str)
Allocates and appends a new buffer containing str as data to ol.
Definition: buffer.c:1225
string_replace_leading
void string_replace_leading(char *str, const char match, const char replace)
Definition: buffer.c:1136
np
const char * np(const char *str)
Definition: buffer.c:904
buf_write
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition: buffer.h:686
buffer_write_file
bool buffer_write_file(const char *filename, const struct buffer *buf)
Write buffer contents to file.
Definition: buffer.c:344
buffer_list_advance
void buffer_list_advance(struct buffer_list *ol, int n)
Definition: buffer.c:1348
buffer_list_aggregate
void buffer_list_aggregate(struct buffer_list *bl, const size_t max)
Aggregates as many buffers as possible from bl in a new buffer of maximum length max_len .
Definition: buffer.c:1325
BPTR
#define BPTR(buf)
Definition: buffer.h:124
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
buf_set_write
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition: buffer.h:331
buffer::offset
int offset
Offset in bytes of the actual content within the allocated memory.
Definition: buffer.h:64
buf_bend
static uint8_t * buf_bend(const struct buffer *buf)
Definition: buffer.h:266
has_digit
static bool has_digit(const char *src)
Definition: buffer.h:372
strncpynt
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:361
buf_init_dowork
static bool buf_init_dowork(struct buffer *buf, int offset)
Definition: buffer.h:319
buf_prepend
static uint8_t * buf_prepend(struct buffer *buf, int size)
Definition: buffer.h:624
buffer_list::tail
struct buffer_entry * tail
Definition: buffer.h:1129
gc_entry_special
Garbage collection entry for a specially allocated structure that needs a custom free function to be ...
Definition: buffer.h:98
alloc_buf
struct buffer alloc_buf(size_t size)
Definition: buffer.c:62
gc_malloc
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition: buffer.c:380
skip_leading_whitespace
const char * skip_leading_whitespace(const char *str)
Definition: buffer.c:623
strprefix
static bool strprefix(const char *str, const char *prefix)
Return true iff str starts with prefix.
Definition: buffer.h:983
convert_to_one_line
void convert_to_one_line(struct buffer *buf)
Definition: buffer.c:329
buffer_list_push_data
struct buffer_entry * buffer_list_push_data(struct buffer_list *ol, const void *data, size_t size)
Allocates and appends a new buffer containing data of length size.
Definition: buffer.c:1239
basic.h
buf_len
static int buf_len(const struct buffer *buf)
Definition: buffer.h:253
buffer_list_pop
void buffer_list_pop(struct buffer_list *ol)
Definition: buffer.c:1331
string_alloc_buf
struct buffer string_alloc_buf(const char *str, struct gc_arena *gc)
Definition: buffer.c:796
buffer_list_defined
bool buffer_list_defined(const struct buffer_list *ol)
Checks if the list is valid and non-empty.
Definition: buffer.c:1204
gc_transfer
void gc_transfer(struct gc_arena *dest, struct gc_arena *src)
Definition: buffer.c:504
array_mult_safe
size_t array_mult_safe(const size_t m1, const size_t m2, const size_t extra)
Definition: buffer.c:41
buf_parse
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition: buffer.c:869
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1039
gc_freeaddrinfo_callback
static void gc_freeaddrinfo_callback(void *addr)
Definition: buffer.h:215
buffer_list_free
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition: buffer.c:1194
buf_sub
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Definition: buffer.c:221
__attribute__
__attribute__((unused))
Definition: test.c:42
buf_read_alloc
static uint8_t * buf_read_alloc(struct buffer *buf, int size)
Definition: buffer.h:672
buf_blast
static uint8_t * buf_blast(const struct buffer *buf)
Definition: buffer.h:272
gc_entry_special::next
struct gc_entry_special * next
Definition: buffer.h:100
buf_write_alloc
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Definition: buffer.h:653
x_gc_free
void x_gc_free(struct gc_arena *a)
Definition: buffer.c:447
gc_init
static void gc_init(struct gc_arena *a)
Definition: buffer.h:1018
gc_entry_special::addr
void * addr
Definition: buffer.h:102
format_hex
static char * format_hex(const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
Definition: buffer.h:523
check_malloc_return
static void check_malloc_return(void *p)
Definition: buffer.h:1109
buffer_list::max_size
int max_size
Definition: buffer.h:1131
buf_str
static char * buf_str(const struct buffer *buf)
Definition: buffer.h:297
buf_read_u8
static int buf_read_u8(struct buffer *buf)
Definition: buffer.h:808
string_class
bool string_class(const char *str, const unsigned int inclusive, const unsigned int exclusive)
Definition: buffer.c:1066
buf_forward_capacity
static int buf_forward_capacity(const struct buffer *buf)
Definition: buffer.h:559
buf_puts
bool buf_puts(struct buffer *buf, const char *str)
Definition: buffer.c:267
buffer_list
Definition: buffer.h:1126
rm_trailing_chars
void rm_trailing_chars(char *str, const char *what_to_delete)
Definition: buffer.c:667
buffer_entry
Definition: buffer.h:1120
buf_defined
static bool buf_defined(const struct buffer *buf)
Definition: buffer.h:228
buf_reverse_capacity
static int buf_reverse_capacity(const struct buffer *buf)
Definition: buffer.h:595
buffer_list::head
struct buffer_entry * head
Definition: buffer.h:1128
buf_set_read
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition: buffer.h:348
buffer_list_reset
void buffer_list_reset(struct buffer_list *ol)
Empty the list ol and frees all the contained buffers.
Definition: buffer.c:1210
buf_copy_n
static bool buf_copy_n(struct buffer *dest, struct buffer *src, int n)
Definition: buffer.h:736
string_mod_const
const char * string_mod_const(const char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace, struct gc_arena *gc)
Returns a copy of a string with certain classes of characters of it replaced with a specified charact...
Definition: buffer.c:1117
BUF_SIZE_MAX
#define BUF_SIZE_MAX
Definition: buffer.h:30
buffer::data
uint8_t * data
Pointer to the allocated memory.
Definition: buffer.h:68