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