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