From 8dd0350e1607aa30f7a043c8d5ec7a7eeb874115 Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Iniesta Date: Mon, 5 Nov 2012 16:28:09 +0100 Subject: Imported Upstream version 2.3_rc1 --- buffer.h | 864 --------------------------------------------------------------- 1 file changed, 864 deletions(-) delete mode 100644 buffer.h (limited to 'buffer.h') diff --git a/buffer.h b/buffer.h deleted file mode 100644 index 3b24d09..0000000 --- a/buffer.h +++ /dev/null @@ -1,864 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef BUFFER_H -#define BUFFER_H - -#include "basic.h" - -#define BUF_SIZE_MAX 1000000 - -/* - * Define verify_align function, otherwise - * it will be a noop. - */ -/* #define VERIFY_ALIGNMENT */ - -/* - * Keep track of source file/line of buf_init calls - */ -#ifdef VERIFY_ALIGNMENT -#define BUF_INIT_TRACKING -#endif - -/* basic buffer class for OpenVPN */ - -struct buffer -{ - int capacity; /* size of buffer allocated by malloc */ - int offset; /* data starts at data + offset, offset > 0 to allow for efficient prepending */ - int len; /* length of data that starts at data + offset */ - uint8_t *data; - -#ifdef BUF_INIT_TRACKING - const char *debug_file; - int debug_line; -#endif -}; - -/* for garbage collection */ - -struct gc_entry -{ - struct gc_entry *next; -}; - -struct gc_arena -{ - struct gc_entry *list; -}; - -#define BPTR(buf) (buf_bptr(buf)) -#define BEND(buf) (buf_bend(buf)) -#define BLAST(buf) (buf_blast(buf)) -#define BLEN(buf) (buf_len(buf)) -#define BDEF(buf) (buf_defined(buf)) -#define BSTR(buf) (buf_str(buf)) -#define BCAP(buf) (buf_forward_capacity (buf)) - -void buf_clear (struct buffer *buf); - -struct buffer clear_buf (void); -void free_buf (struct buffer *buf); - -bool buf_assign (struct buffer *dest, const struct buffer *src); - -void string_clear (char *str); -int string_array_len (const char **array); - -size_t array_mult_safe (const size_t m1, const size_t m2, const size_t extra); - -#define PA_BRACKET (1<<0) -char *print_argv (const char **p, struct gc_arena *gc, const unsigned int flags); - -void buf_size_error (const size_t size); - -/* for dmalloc debugging */ - -#ifdef DMALLOC - -#define alloc_buf(size) alloc_buf_debug (size, __FILE__, __LINE__) -#define alloc_buf_gc(size, gc) alloc_buf_gc_debug (size, gc, __FILE__, __LINE__); -#define clone_buf(buf) clone_buf_debug (buf, __FILE__, __LINE__); -#define gc_malloc(size, clear, arena) gc_malloc_debug (size, clear, arena, __FILE__, __LINE__) -#define string_alloc(str, gc) string_alloc_debug (str, gc, __FILE__, __LINE__) -#define string_alloc_buf(str, gc) string_alloc_buf_debug (str, gc, __FILE__, __LINE__) - -struct buffer alloc_buf_debug (size_t size, const char *file, int line); -struct buffer alloc_buf_gc_debug (size_t size, struct gc_arena *gc, const char *file, int line); -struct buffer clone_buf_debug (const struct buffer* buf, const char *file, int line); -void *gc_malloc_debug (size_t size, bool clear, struct gc_arena *a, const char *file, int line); -char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file, int line); -struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line); - -#else - -struct buffer alloc_buf (size_t size); -struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */ -struct buffer clone_buf (const struct buffer* buf); -void *gc_malloc (size_t size, bool clear, struct gc_arena *a); -char *string_alloc (const char *str, struct gc_arena *gc); -struct buffer string_alloc_buf (const char *str, struct gc_arena *gc); - -#endif - -#ifdef BUF_INIT_TRACKING -#define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__) -bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line); -#else -#define buf_init(buf, offset) buf_init_dowork (buf, offset) -#endif - - -/* inline functions */ - -static inline bool -buf_defined (const struct buffer *buf) -{ - return buf->data != NULL; -} - -static inline bool -buf_valid (const struct buffer *buf) -{ - return likely (buf->data != NULL) && likely (buf->len >= 0); -} - -static inline uint8_t * -buf_bptr (const struct buffer *buf) -{ - if (buf_valid (buf)) - return buf->data + buf->offset; - else - return NULL; -} - -static int -buf_len (const struct buffer *buf) -{ - if (buf_valid (buf)) - return buf->len; - else - return 0; -} - -static inline uint8_t * -buf_bend (const struct buffer *buf) -{ - return buf_bptr (buf) + buf_len (buf); -} - -static inline uint8_t * -buf_blast (const struct buffer *buf) -{ - if (buf_len (buf) > 0) - return buf_bptr (buf) + buf_len (buf) - 1; - else - return NULL; -} - -static inline bool -buf_size_valid (const size_t size) -{ - return likely (size < BUF_SIZE_MAX); -} - -static inline bool -buf_size_valid_signed (const int size) -{ - return likely (size >= -BUF_SIZE_MAX) && likely (size < BUF_SIZE_MAX); -} - -static inline char * -buf_str (const struct buffer *buf) -{ - return (char *)buf_bptr(buf); -} - -static inline void -buf_reset (struct buffer *buf) -{ - buf->capacity = 0; - buf->offset = 0; - buf->len = 0; - buf->data = NULL; -} - -static inline void -buf_reset_len (struct buffer *buf) -{ - buf->len = 0; - buf->offset = 0; -} - -static inline bool -buf_init_dowork (struct buffer *buf, int offset) -{ - if (offset < 0 || offset > buf->capacity || buf->data == NULL) - return false; - buf->len = 0; - buf->offset = offset; - return true; -} - -static inline void -buf_set_write (struct buffer *buf, uint8_t *data, int size) -{ - if (!buf_size_valid (size)) - buf_size_error (size); - buf->len = 0; - buf->offset = 0; - buf->capacity = size; - buf->data = data; - if (size > 0 && data) - *data = 0; -} - -static inline void -buf_set_read (struct buffer *buf, const uint8_t *data, int size) -{ - if (!buf_size_valid (size)) - buf_size_error (size); - buf->len = buf->capacity = size; - buf->offset = 0; - buf->data = (uint8_t *)data; -} - -/* Like strncpy but makes sure dest is always null terminated */ -static inline void -strncpynt (char *dest, const char *src, size_t maxlen) -{ - strncpy (dest, src, maxlen); - if (maxlen > 0) - dest[maxlen - 1] = 0; -} - -/* return true if string contains at least one numerical digit */ -static inline bool -has_digit (const unsigned char* src) -{ - unsigned char c; - while ((c = *src++)) - { - if (isdigit(c)) - return true; - } - return false; -} - -/* - * printf append to a buffer with overflow check - */ -bool buf_printf (struct buffer *buf, const char *format, ...) -#ifdef __GNUC__ - __attribute__ ((format (printf, 2, 3))) -#endif - ; - -/* - * Like snprintf but guarantees null termination for size > 0 - */ -int openvpn_snprintf(char *str, size_t size, const char *format, ...) -#ifdef __GNUC__ - __attribute__ ((format (printf, 3, 4))) -#endif - ; - -/* - * remove/add trailing characters - */ - -void buf_null_terminate (struct buffer *buf); -void buf_chomp (struct buffer *buf); -void buf_rmtail (struct buffer *buf, uint8_t remove); - -/* - * non-buffer string functions - */ -void chomp (char *str); -void rm_trailing_chars (char *str, const char *what_to_delete); -const char *skip_leading_whitespace (const char *str); -void string_null_terminate (char *str, int len, int capacity); - -/* - * Write string in buf to file descriptor fd. - * NOTE: requires that string be null terminated. - */ -void buf_write_string_file (const struct buffer *buf, const char *filename, int fd); - -/* - * write a string to the end of a buffer that was - * truncated by buf_printf - */ -void buf_catrunc (struct buffer *buf, const char *str); - -/* - * convert a multi-line output to one line - */ -void convert_to_one_line (struct buffer *buf); - -/* - * Parse a string based on a given delimiter char - */ -bool buf_parse (struct buffer *buf, const int delim, char *line, const int size); - -/* - * Hex dump -- Output a binary buffer to a hex string and return it. - */ -char * -format_hex_ex (const uint8_t *data, int size, int maxoutput, - int space_break, const char* separator, - struct gc_arena *gc); - -static inline char * -format_hex (const uint8_t *data, int size, int maxoutput, struct gc_arena *gc) -{ - return format_hex_ex (data, size, maxoutput, 4, " ", gc); -} - -/* - * Return a buffer that is a subset of another buffer. - */ -struct buffer buf_sub (struct buffer *buf, int size, bool prepend); - -/* - * Check if sufficient space to append to buffer. - */ - -static inline bool -buf_safe (const struct buffer *buf, int len) -{ - return buf_valid (buf) && buf_size_valid (len) - && buf->offset + buf->len + len <= buf->capacity; -} - -static inline bool -buf_safe_bidir (const struct buffer *buf, int len) -{ - if (buf_valid (buf) && buf_size_valid_signed (len)) - { - const int newlen = buf->len + len; - return newlen >= 0 && buf->offset + newlen <= buf->capacity; - } - else - return false; -} - -static inline int -buf_forward_capacity (const struct buffer *buf) -{ - if (buf_valid (buf)) - { - int ret = buf->capacity - (buf->offset + buf->len); - if (ret < 0) - ret = 0; - return ret; - } - else - return 0; -} - -static inline int -buf_forward_capacity_total (const struct buffer *buf) -{ - if (buf_valid (buf)) - { - int ret = buf->capacity - buf->offset; - if (ret < 0) - ret = 0; - return ret; - } - else - return 0; -} - -static inline int -buf_reverse_capacity (const struct buffer *buf) -{ - if (buf_valid (buf)) - return buf->offset; - else - return 0; -} - -static inline bool -buf_inc_len (struct buffer *buf, int inc) -{ - if (!buf_safe_bidir (buf, inc)) - return false; - buf->len += inc; - return true; -} - -/* - * Make space to prepend to a buffer. - * Return NULL if no space. - */ - -static inline uint8_t * -buf_prepend (struct buffer *buf, int size) -{ - if (!buf_valid (buf) || size < 0 || size > buf->offset) - return NULL; - buf->offset -= size; - buf->len += size; - return BPTR (buf); -} - -static inline bool -buf_advance (struct buffer *buf, int size) -{ - if (!buf_valid (buf) || size < 0 || buf->len < size) - return false; - buf->offset += size; - buf->len -= size; - return true; -} - -/* - * Return a pointer to allocated space inside a buffer. - * Return NULL if no space. - */ - -static inline uint8_t * -buf_write_alloc (struct buffer *buf, int size) -{ - uint8_t *ret; - if (!buf_safe (buf, size)) - return NULL; - ret = BPTR (buf) + buf->len; - buf->len += size; - return ret; -} - -static inline uint8_t * -buf_write_alloc_prepend (struct buffer *buf, int size, bool prepend) -{ - return prepend ? buf_prepend (buf, size) : buf_write_alloc (buf, size); -} - -static inline uint8_t * -buf_read_alloc (struct buffer *buf, int size) -{ - uint8_t *ret; - if (size < 0 || buf->len < size) - return NULL; - ret = BPTR (buf); - buf->offset += size; - buf->len -= size; - return ret; -} - -static inline bool -buf_write (struct buffer *dest, const void *src, int size) -{ - uint8_t *cp = buf_write_alloc (dest, size); - if (!cp) - return false; - memcpy (cp, src, size); - return true; -} - -static inline bool -buf_write_prepend (struct buffer *dest, const void *src, int size) -{ - uint8_t *cp = buf_prepend (dest, size); - if (!cp) - return false; - memcpy (cp, src, size); - return true; -} - -static inline bool -buf_write_u8 (struct buffer *dest, int data) -{ - uint8_t u8 = (uint8_t) data; - return buf_write (dest, &u8, sizeof (uint8_t)); -} - -static inline bool -buf_write_u16 (struct buffer *dest, int data) -{ - uint16_t u16 = htons ((uint16_t) data); - return buf_write (dest, &u16, sizeof (uint16_t)); -} - -static inline bool -buf_write_u32 (struct buffer *dest, int data) -{ - uint32_t u32 = htonl ((uint32_t) data); - return buf_write (dest, &u32, sizeof (uint32_t)); -} - -static inline bool -buf_copy (struct buffer *dest, const struct buffer *src) -{ - return buf_write (dest, BPTR (src), BLEN (src)); -} - -static inline bool -buf_copy_n (struct buffer *dest, struct buffer *src, int n) -{ - uint8_t *cp = buf_read_alloc (src, n); - if (!cp) - return false; - return buf_write (dest, cp, n); -} - -static inline bool -buf_copy_range (struct buffer *dest, - int dest_index, - const struct buffer *src, - int src_index, - int src_len) -{ - if (src_index < 0 - || src_len < 0 - || src_index + src_len > src->len - || dest_index < 0 - || dest->offset + dest_index + src_len > dest->capacity) - return false; - memcpy (dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len); - if (dest_index + src_len > dest->len) - dest->len = dest_index + src_len; - return true; -} - -/* truncate src to len, copy excess data beyond len to dest */ -static inline bool -buf_copy_excess (struct buffer *dest, - struct buffer *src, - int len) -{ - if (len < 0) - return false; - if (src->len > len) - { - struct buffer b = *src; - src->len = len; - if (!buf_advance (&b, len)) - return false; - return buf_copy (dest, &b); - } - else - { - return true; - } -} - -static inline bool -buf_read (struct buffer *src, void *dest, int size) -{ - uint8_t *cp = buf_read_alloc (src, size); - if (!cp) - return false; - memcpy (dest, cp, size); - return true; -} - -static inline int -buf_read_u8 (struct buffer *buf) -{ - int ret; - if (BLEN (buf) < 1) - return -1; - ret = *BPTR(buf); - buf_advance (buf, 1); - return ret; -} - -static inline int -buf_read_u16 (struct buffer *buf) -{ - uint16_t ret; - if (!buf_read (buf, &ret, sizeof (uint16_t))) - return -1; - return ntohs (ret); -} - -static inline uint32_t -buf_read_u32 (struct buffer *buf, bool *good) -{ - uint32_t ret; - if (!buf_read (buf, &ret, sizeof (uint32_t))) - { - if (good) - *good = false; - return 0; - } - else - { - if (good) - *good = true; - return ntohl (ret); - } -} - -static inline bool -buf_string_match (const struct buffer *src, const void *match, int size) -{ - if (size != src->len) - return false; - return memcmp (BPTR (src), match, size) == 0; -} - -static inline bool -buf_string_match_head (const struct buffer *src, const void *match, int size) -{ - if (size < 0 || size > src->len) - return false; - return memcmp (BPTR (src), match, size) == 0; -} - -bool buf_string_match_head_str (const struct buffer *src, const char *match); -bool buf_string_compare_advance (struct buffer *src, const char *match); -int buf_substring_len (const struct buffer *buf, int delim); - -/* - * Bitwise operations - */ -static inline void -xor (uint8_t *dest, const uint8_t *src, int len) -{ - while (len-- > 0) - *dest++ ^= *src++; -} - -/* - * Print a string which might be NULL - */ -const char *np (const char *str); - -/*#define CHARACTER_CLASS_DEBUG*/ - -/* character classes */ - -#define CC_ANY (1<<0) -#define CC_NULL (1<<1) - -#define CC_ALNUM (1<<2) -#define CC_ALPHA (1<<3) -#define CC_ASCII (1<<4) -#define CC_CNTRL (1<<5) -#define CC_DIGIT (1<<6) -#define CC_PRINT (1<<7) -#define CC_PUNCT (1<<8) -#define CC_SPACE (1<<9) -#define CC_XDIGIT (1<<10) - -#define CC_BLANK (1<<11) -#define CC_NEWLINE (1<<12) -#define CC_CR (1<<13) - -#define CC_BACKSLASH (1<<14) -#define CC_UNDERBAR (1<<15) -#define CC_DASH (1<<16) -#define CC_DOT (1<<17) -#define CC_COMMA (1<<18) -#define CC_COLON (1<<19) -#define CC_SLASH (1<<20) -#define CC_SINGLE_QUOTE (1<<21) -#define CC_DOUBLE_QUOTE (1<<22) -#define CC_REVERSE_QUOTE (1<<23) -#define CC_AT (1<<24) -#define CC_EQUAL (1<<25) - -/* macro classes */ -#define CC_NAME (CC_ALNUM|CC_UNDERBAR) -#define CC_CRLF (CC_CR|CC_NEWLINE) - -bool char_class (const unsigned char c, const unsigned int flags); -bool string_class (const char *str, const unsigned int inclusive, const unsigned int exclusive); -bool string_mod (char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace); - -const char *string_mod_const (const char *str, - const unsigned int inclusive, - const unsigned int exclusive, - const char replace, - struct gc_arena *gc); - -void string_replace_leading (char *str, const char match, const char replace); - -#ifdef CHARACTER_CLASS_DEBUG -void character_class_debug (void); -#endif - -/* - * Verify that a pointer is correctly aligned - */ -#ifdef VERIFY_ALIGNMENT - void valign4 (const struct buffer *buf, const char *file, const int line); -# define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__) -#else -# define verify_align_4(ptr) -#endif - -/* - * Very basic garbage collection, mostly for routines that return - * char ptrs to malloced strings. - */ - -void gc_transfer (struct gc_arena *dest, struct gc_arena *src); - -void x_gc_free (struct gc_arena *a); - -static inline bool -gc_defined (struct gc_arena *a) -{ - return a->list != NULL; -} - -static inline void -gc_init (struct gc_arena *a) -{ - a->list = NULL; -} - -static inline void -gc_detach (struct gc_arena *a) -{ - gc_init (a); -} - -static inline struct gc_arena -gc_new (void) -{ - struct gc_arena ret; - ret.list = NULL; - return ret; -} - -static inline void -gc_free (struct gc_arena *a) -{ - if (a->list) - x_gc_free (a); -} - -static inline void -gc_reset (struct gc_arena *a) -{ - gc_free (a); -} - -/* - * Allocate memory to hold a structure - */ - -void out_of_memory (void); - -#define ALLOC_OBJ(dptr, type) \ -{ \ - check_malloc_return ((dptr) = (type *) malloc (sizeof (type))); \ -} - -#define ALLOC_OBJ_CLEAR(dptr, type) \ -{ \ - ALLOC_OBJ (dptr, type); \ - memset ((dptr), 0, sizeof(type)); \ -} - -#define ALLOC_ARRAY(dptr, type, n) \ -{ \ - check_malloc_return ((dptr) = (type *) malloc (array_mult_safe (sizeof (type), (n), 0))); \ -} - -#define ALLOC_ARRAY_GC(dptr, type, n, gc) \ -{ \ - (dptr) = (type *) gc_malloc (array_mult_safe (sizeof (type), (n), 0), false, (gc)); \ -} - -#define ALLOC_ARRAY_CLEAR(dptr, type, n) \ -{ \ - ALLOC_ARRAY (dptr, type, n); \ - memset ((dptr), 0, (array_mult_safe (sizeof(type), (n), 0))); \ -} - -#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \ -{ \ - (dptr) = (type *) gc_malloc (array_mult_safe (sizeof (type), (n), 0), true, (gc)); \ -} - -#define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \ -{ \ - (dptr) = (type *) gc_malloc (array_mult_safe (sizeof (atype), (n), sizeof (type)), true, (gc)); \ -} - -#define ALLOC_OBJ_GC(dptr, type, gc) \ -{ \ - (dptr) = (type *) gc_malloc (sizeof (type), false, (gc)); \ -} - -#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \ -{ \ - (dptr) = (type *) gc_malloc (sizeof (type), true, (gc)); \ -} - -static inline void -check_malloc_return (void *p) -{ - void out_of_memory (void); - if (!p) - out_of_memory (); -} - -/* - * Manage lists of buffers - */ - -#ifdef ENABLE_BUFFER_LIST - -struct buffer_entry -{ - struct buffer buf; - struct buffer_entry *next; -}; - -struct buffer_list -{ - struct buffer_entry *head; /* next item to pop/peek */ - struct buffer_entry *tail; /* last item pushed */ - int size; /* current number of entries */ - int max_size; /* maximum size list should grow to */ -}; - -struct buffer_list *buffer_list_new (const int max_size); -void buffer_list_free (struct buffer_list *ol); - -bool buffer_list_defined (const struct buffer_list *ol); -void buffer_list_reset (struct buffer_list *ol); - -void buffer_list_push (struct buffer_list *ol, const unsigned char *str); -struct buffer_entry *buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size); -struct buffer *buffer_list_peek (struct buffer_list *ol); -void buffer_list_advance (struct buffer_list *ol, int n); -void buffer_list_pop (struct buffer_list *ol); - -void buffer_list_aggregate (struct buffer_list *bl, const size_t max); - -struct buffer_list *buffer_list_file (const char *fn, int max_line_len); - -#endif - -#endif /* BUFFER_H */ -- cgit v1.2.3