summaryrefslogtreecommitdiff
path: root/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn')
-rw-r--r--openvpn/basic.h41
-rw-r--r--openvpn/buffer.h712
-rw-r--r--openvpn/common.h76
-rw-r--r--openvpn/event.h157
-rw-r--r--openvpn/integer.h114
-rw-r--r--openvpn/interval.h239
-rw-r--r--openvpn/misc.h257
-rw-r--r--openvpn/mtu.h304
-rw-r--r--openvpn/otime.h206
-rw-r--r--openvpn/perf.h82
-rw-r--r--openvpn/proto.h163
-rw-r--r--openvpn/sig.h100
-rw-r--r--openvpn/status.h95
-rw-r--r--openvpn/thread.h235
-rwxr-xr-xopenvpn/win32.h251
15 files changed, 3032 insertions, 0 deletions
diff --git a/openvpn/basic.h b/openvpn/basic.h
new file mode 100644
index 0000000..cde638e
--- /dev/null
+++ b/openvpn/basic.h
@@ -0,0 +1,41 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 BASIC_H
+#define BASIC_H
+
+/* bool definitions */
+#define bool int
+#define true 1
+#define false 0
+
+#define BOOL_CAST(x) ((x) ? (true) : (false))
+
+/* size of an array */
+#define SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+/* clear an object */
+#define CLEAR(x) memset(&(x), 0, sizeof(x))
+
+#endif
diff --git a/openvpn/buffer.h b/openvpn/buffer.h
new file mode 100644
index 0000000..1e5266b
--- /dev/null
+++ b/openvpn/buffer.h
@@ -0,0 +1,712 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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"
+#include "thread.h"
+
+/*
+ * 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)->data + (buf)->offset)
+#define BEND(buf) (BPTR(buf) + (buf)->len)
+#define BLAST(buf) (((buf)->data && (buf)->len) ? (BPTR(buf) + (buf)->len - 1) : NULL)
+#define BLEN(buf) ((buf)->len)
+#define BDEF(buf) ((buf)->data != NULL)
+#define BSTR(buf) ((char *)BPTR(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);
+
+
+
+/* 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 void
+buf_reset (struct buffer *buf)
+{
+ buf->capacity = 0;
+ buf->offset = 0;
+ buf->len = 0;
+ buf->data = NULL;
+}
+
+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 bool
+buf_defined (struct buffer *buf)
+{
+ return buf->data != NULL;
+}
+
+static inline void
+buf_set_write (struct buffer *buf, uint8_t *data, int 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)
+{
+ 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 char* src)
+{
+ char c;
+ while ((c = *src++))
+ {
+ if (isdigit(c))
+ return true;
+ }
+ return false;
+}
+
+/*
+ * printf append to a buffer with overflow check
+ */
+void 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 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 len >= 0 && buf->offset + buf->len + len <= buf->capacity;
+}
+
+static inline bool
+buf_safe_bidir (const struct buffer *buf, int len)
+{
+ const int newlen = buf->len + len;
+ return newlen >= 0 && buf->offset + newlen <= buf->capacity;
+}
+
+static inline int
+buf_forward_capacity (const struct buffer *buf)
+{
+ int ret = buf->capacity - (buf->offset + buf->len);
+ if (ret < 0)
+ ret = 0;
+ return ret;
+}
+
+static inline int
+buf_forward_capacity_total (const struct buffer *buf)
+{
+ int ret = buf->capacity - buf->offset;
+ if (ret < 0)
+ ret = 0;
+ return ret;
+}
+
+static inline int
+buf_reverse_capacity (const struct buffer *buf)
+{
+ return buf->offset;
+}
+
+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 (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 (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++;
+}
+
+/*
+ * Classify and mutate strings based on character types.
+ */
+
+/*#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 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);
+
+#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 x_gc_free (struct gc_arena *a);
+
+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 (sizeof (type) * (n))); \
+}
+
+#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
+{ \
+ (dptr) = (type *) gc_malloc (sizeof (type) * (n), false, (gc)); \
+}
+
+#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
+{ \
+ ALLOC_ARRAY (dptr, type, n); \
+ memset ((dptr), 0, (sizeof(type) * (n))); \
+}
+
+#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
+{ \
+ (dptr) = (type *) gc_malloc (sizeof (type) * (n), 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 ();
+}
+
+#endif /* BUFFER_H */
diff --git a/openvpn/common.h b/openvpn/common.h
new file mode 100644
index 0000000..70efdbf
--- /dev/null
+++ b/openvpn/common.h
@@ -0,0 +1,76 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 COMMON_H
+#define COMMON_H
+
+/*
+ * Statistics counters and associated printf formats.
+ */
+#ifdef USE_64_BIT_COUNTERS
+ typedef unsigned long long int counter_type;
+# ifdef WIN32
+# define counter_format "%I64u"
+# else
+# define counter_format "%llu"
+# endif
+#else
+ typedef unsigned int counter_type;
+# define counter_format "%u"
+#endif
+
+/*
+ * Time intervals
+ */
+typedef int interval_t;
+
+/*
+ * Used as an upper bound for timeouts.
+ */
+#define BIG_TIMEOUT (60*60*24*7) /* one week (in seconds) */
+
+/*
+ * Printf formats for special types
+ */
+#define ptr_format "0x%08lx"
+#define time_format "%lu"
+#define fragment_header_format "0x%08x"
+
+/* these are used to cast the arguments
+ * and MUST match the formats above */
+typedef unsigned long time_type;
+typedef unsigned long ptr_type;
+
+/* the --client-config-dir default file */
+#define CCD_DEFAULT "DEFAULT"
+
+/*
+ * This parameter controls the TLS channel buffer size. Among
+ * other things, this buffer must be large enough to contain
+ * the full --push/--pull list. If you increase it, do so
+ * on both server and client.
+ */
+#define TLS_CHANNEL_BUF_SIZE 1024
+
+#endif
diff --git a/openvpn/event.h b/openvpn/event.h
new file mode 100644
index 0000000..314ef4c
--- /dev/null
+++ b/openvpn/event.h
@@ -0,0 +1,157 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 EVENT_H
+#define EVENT_H
+
+#include "win32.h"
+#include "sig.h"
+#include "perf.h"
+
+/*
+ * rwflags passed to event_ctl and returned by
+ * struct event_set_return.
+ */
+#define EVENT_READ (1<<0)
+#define EVENT_WRITE (1<<1)
+
+/*
+ * Initialization flags passed to event_set_init
+ */
+#define EVENT_METHOD_US_TIMEOUT (1<<0)
+#define EVENT_METHOD_FAST (1<<1)
+
+#ifdef WIN32
+
+typedef const struct rw_handle *event_t;
+
+#define UNDEFINED_EVENT (NULL)
+
+#else
+
+typedef int event_t;
+
+#define UNDEFINED_EVENT (-1)
+
+#endif
+
+struct event_set;
+struct event_set_return;
+
+struct event_set_functions
+{
+ void (*free)(struct event_set *es);
+ void (*reset)(struct event_set *es);
+ void (*del)(struct event_set *es, event_t event);
+ void (*ctl)(struct event_set *es, event_t event, unsigned int rwflags, void *arg);
+
+ /*
+ * Return status for wait:
+ * -1 on signal or error
+ * 0 on timeout
+ * length of event_set_return if at least 1 event is returned
+ */
+ int (*wait)(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen);
+};
+
+struct event_set_return
+{
+ unsigned int rwflags;
+ void *arg;
+};
+
+struct event_set
+{
+ struct event_set_functions func;
+};
+
+/*
+ * maxevents on input: desired max number of event_t descriptors
+ * simultaneously set with event_ctl
+ * maxevents on output: may be modified down, depending on limitations
+ * of underlying API
+ * flags: EVENT_METHOD_x flags
+ */
+struct event_set *event_set_init (int *maxevents, unsigned int flags);
+
+static inline void
+event_free (struct event_set *es)
+{
+ (*es->func.free)(es);
+}
+
+static inline void
+event_reset (struct event_set *es)
+{
+ (*es->func.reset)(es);
+}
+
+static inline void
+event_del (struct event_set *es, event_t event)
+{
+ (*es->func.del)(es, event);
+}
+
+static inline void
+event_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg)
+{
+ (*es->func.ctl)(es, event, rwflags, arg);
+}
+
+static inline int
+event_wait (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
+{
+ int ret;
+ perf_push (PERF_IO_WAIT);
+ ret = (*es->func.wait)(es, tv, out, outlen);
+ perf_pop ();
+ return ret;
+}
+
+static inline void
+event_set_return_init (struct event_set_return *esr)
+{
+ esr->rwflags = 0;
+ esr->arg = NULL;
+}
+
+#ifdef WIN32
+
+static inline void
+wait_signal (struct event_set *es, void *arg)
+{
+ if (HANDLE_DEFINED (win32_signal.in.read))
+ event_ctl (es, &win32_signal.in, EVENT_READ, arg);
+}
+
+#else
+
+static inline void
+wait_signal (struct event_set *es, void *arg)
+{
+}
+
+#endif
+
+#endif
diff --git a/openvpn/integer.h b/openvpn/integer.h
new file mode 100644
index 0000000..68cf40f
--- /dev/null
+++ b/openvpn/integer.h
@@ -0,0 +1,114 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 INTEGER_H
+#define INTEGER_H
+
+#include "error.h"
+
+/*
+ * min/max functions
+ */
+
+static inline int
+max_int (int x, int y)
+{
+ if (x > y)
+ return x;
+ else
+ return y;
+}
+
+static inline int
+min_int (int x, int y)
+{
+ if (x < y)
+ return x;
+ else
+ return y;
+}
+
+static inline int
+constrain_int (int x, int min, int max)
+{
+ if (min > max)
+ return min;
+ if (x < min)
+ return min;
+ else if (x > max)
+ return max;
+ else
+ return x;
+}
+
+/*
+ * Functions used for circular buffer index arithmetic.
+ */
+
+/*
+ * Return x - y on a circle of circumference mod by shortest path.
+ *
+ * 0 <= x < mod
+ * 0 <= y < mod
+ */
+static inline int
+modulo_subtract(int x, int y, int mod)
+{
+ const int d1 = x - y;
+ const int d2 = (x > y ? -mod : mod) + d1;
+ ASSERT (0 <= x && x < mod && 0 <= y && y < mod);
+ return abs(d1) > abs(d2) ? d2 : d1;
+}
+
+/*
+ * Return x + y on a circle of circumference mod.
+ *
+ * 0 <= x < mod
+ * -mod <= y <= mod
+ */
+static inline int
+modulo_add(int x, int y, int mod)
+{
+ int sum = x + y;
+ ASSERT (0 <= x && x < mod && -mod <= y && y <= mod);
+ if (sum >= mod)
+ sum -= mod;
+ if (sum < 0)
+ sum += mod;
+ return sum;
+}
+
+static inline int
+index_verify (int index, int size, const char *file, int line)
+{
+ if (index < 0 || index >= size)
+ msg (M_FATAL, "Assertion Failed: Array index=%d out of bounds for array size=%d in %s:%d",
+ index,
+ size,
+ file,
+ line);
+ return index;
+}
+
+#endif
diff --git a/openvpn/interval.h b/openvpn/interval.h
new file mode 100644
index 0000000..9845066
--- /dev/null
+++ b/openvpn/interval.h
@@ -0,0 +1,239 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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
+ */
+
+/*
+ * The interval_ routines are designed to optimize the calling of a routine
+ * (normally tls_multi_process()) which can be called less frequently
+ * between triggers.
+ */
+
+#ifndef INTERVAL_H
+#define INTERVAL_H
+
+#include "otime.h"
+
+#define INTERVAL_DEBUG 0
+
+/*
+ * Designed to limit calls to expensive functions that need to be called
+ * regularly.
+ */
+
+struct interval
+{
+ interval_t refresh;
+ interval_t horizon;
+ time_t future_trigger;
+ time_t last_action;
+ time_t last_test_true;
+};
+
+void interval_init (struct interval *top, int horizon, int refresh);
+
+/*
+ * IF
+ * last_action less than horizon seconds ago
+ * OR last_test_true more than refresh seconds ago
+ * OR hit future_trigger
+ * THEN
+ * return true
+ * ELSE
+ * set wakeup to the number of seconds until a true return
+ * return false
+ */
+
+static inline bool
+interval_test (struct interval* top)
+{
+ bool trigger = false;
+ const time_t local_now = now;
+
+ if (top->future_trigger && local_now >= top->future_trigger)
+ {
+ trigger = true;
+ top->future_trigger = 0;
+ }
+
+ if (top->last_action + top->horizon > local_now ||
+ top->last_test_true + top->refresh <= local_now ||
+ trigger)
+ {
+ top->last_test_true = local_now;
+#if INTERVAL_DEBUG
+ dmsg (D_INTERVAL, "INTERVAL interval_test true");
+#endif
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static inline void
+interval_schedule_wakeup (struct interval* top, interval_t *wakeup)
+{
+ const time_t local_now = now;
+ interval_earliest_wakeup (wakeup, top->last_test_true + top->refresh, local_now);
+ interval_earliest_wakeup (wakeup, top->future_trigger, local_now);
+#if INTERVAL_DEBUG
+ dmsg (D_INTERVAL, "INTERVAL interval_schedule wakeup=%d", (int)*wakeup);
+#endif
+}
+
+/*
+ * In wakeup seconds, interval_test will return true once.
+ */
+static inline void
+interval_future_trigger (struct interval* top, interval_t wakeup) {
+ if (wakeup)
+ {
+#if INTERVAL_DEBUG
+ dmsg (D_INTERVAL, "INTERVAL interval_future_trigger %d", (int)wakeup);
+#endif
+ top->future_trigger = now + wakeup;
+ }
+}
+
+/*
+ * Once an action is triggered, interval_test will remain true for
+ * horizon seconds.
+ */
+static inline void
+interval_action (struct interval* top)
+{
+#if INTERVAL_DEBUG
+ dmsg (D_INTERVAL, "INTERVAL action");
+#endif
+ top->last_action = now;
+}
+
+/*
+ * Measure when n seconds beyond an event have elapsed
+ */
+
+struct event_timeout
+{
+ bool defined;
+ interval_t n;
+ time_t last; /* time of last event */
+};
+
+static inline bool
+event_timeout_defined (const struct event_timeout* et)
+{
+ return et->defined;
+}
+
+static inline void
+event_timeout_clear (struct event_timeout* et)
+{
+ et->defined = false;
+ et->n = 0;
+ et->last = 0;
+}
+
+static inline struct event_timeout
+event_timeout_clear_ret ()
+{
+ struct event_timeout ret;
+ event_timeout_clear (&ret);
+ return ret;
+}
+
+static inline void
+event_timeout_init (struct event_timeout* et, interval_t n, const time_t local_now)
+{
+ et->defined = true;
+ et->n = (n >= 0) ? n : 0;
+ et->last = local_now;
+}
+
+static inline void
+event_timeout_reset (struct event_timeout* et)
+{
+ if (et->defined)
+ et->last = now;
+}
+
+/*
+ * This is the principal function for testing and triggering recurring
+ * timers and will return true on a timer signal event.
+ * If et_const_retry == ETT_DEFAULT and a signal occurs,
+ * the function will return true and *et will be armed for the
+ * next event. If et_const_retry >= 0 and a signal occurs,
+ * *et will not be touched, but *tv will be set to
+ * minimum (*tv, et_const_retry) for a future re-test,
+ * and the function will return true.
+ */
+
+#define ETT_DEFAULT (-1)
+
+bool event_timeout_trigger (struct event_timeout *et,
+ struct timeval *tv,
+ const int et_const_retry);
+
+/*
+ * Measure time intervals in microseconds
+ */
+
+#define USEC_TIMER_MAX 60 /* maximum interval size in seconds */
+
+#define USEC_TIMER_MAX_USEC (USEC_TIMER_MAX * 1000000)
+
+struct usec_timer {
+ struct timeval start;
+ struct timeval end;
+};
+
+#ifdef HAVE_GETTIMEOFDAY
+
+static inline void
+usec_timer_start (struct usec_timer *obj)
+{
+ CLEAR (*obj);
+ gettimeofday (&obj->start, NULL);
+}
+
+static inline void
+usec_timer_end (struct usec_timer *obj)
+{
+ gettimeofday (&obj->end, NULL);
+}
+
+#endif /* HAVE_GETTIMEOFDAY */
+
+static inline bool
+usec_timer_interval_defined (struct usec_timer *obj)
+{
+ return obj->start.tv_sec && obj->end.tv_sec;
+}
+
+static inline int
+usec_timer_interval (struct usec_timer *obj)
+{
+ return tv_subtract (&obj->end, &obj->start, USEC_TIMER_MAX);
+}
+
+#endif /* INTERVAL_H */
diff --git a/openvpn/misc.h b/openvpn/misc.h
new file mode 100644
index 0000000..00ddae8
--- /dev/null
+++ b/openvpn/misc.h
@@ -0,0 +1,257 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 MISC_H
+#define MISC_H
+
+#include "basic.h"
+#include "common.h"
+#include "integer.h"
+#include "buffer.h"
+
+/* socket descriptor passed by inetd/xinetd server to us */
+#define INETD_SOCKET_DESCRIPTOR 0
+
+/* forward declarations */
+struct plugin_list;
+
+/*
+ * Handle environmental variable lists
+ */
+
+struct env_item {
+ char *string;
+ struct env_item *next;
+};
+
+struct env_set {
+ struct gc_arena *gc;
+ struct env_item *list;
+};
+
+/* Get/Set UID of process */
+
+struct user_state {
+#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID)
+ const char *username;
+ struct passwd *pw;
+#else
+ int dummy;
+#endif
+};
+
+bool get_user (const char *username, struct user_state *state);
+void set_user (const struct user_state *state);
+
+/* Get/Set GID of process */
+
+struct group_state {
+#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID)
+ const char *groupname;
+ struct group *gr;
+#else
+ int dummy;
+#endif
+};
+
+bool get_group (const char *groupname, struct group_state *state);
+void set_group (const struct group_state *state);
+
+void set_nice (int niceval);
+void do_chroot (const char *path);
+
+void run_up_down (const char *command,
+ const struct plugin_list *plugins,
+ int plugin_type,
+ const char *arg,
+ int tun_mtu,
+ int link_mtu,
+ const char *ifconfig_local,
+ const char* ifconfig_remote,
+ const char *context,
+ const char *signal_text,
+ const char *script_type,
+ struct env_set *es);
+
+/* workspace for get_pid_file/write_pid */
+struct pid_state {
+ FILE *fp;
+ const char *filename;
+};
+
+void get_pid_file (const char* filename, struct pid_state *state);
+void write_pid (const struct pid_state *state);
+unsigned int openvpn_getpid (void);
+
+void do_mlockall (bool print_msg); /* Disable paging */
+
+#ifndef HAVE_DAEMON
+int daemon (int nochdir, int noclose);
+#endif
+
+/* check file protections */
+void warn_if_group_others_accessible(const char* filename);
+
+/* system flags */
+#define S_SCRIPT (1<<0)
+#define S_FATAL (1<<1)
+
+/* wrapper around the system() call. */
+int openvpn_system (const char *command, const struct env_set *es, unsigned int flags);
+
+/* interpret the status code returned by system() */
+bool system_ok(int);
+int system_executed (int stat);
+const char *system_error_message (int, struct gc_arena *gc);
+
+/* run system() with error check, return true if success,
+ false if error, exit if error and fatal==true */
+bool system_check (const char *command, const struct env_set *es, unsigned int flags, const char *error_message);
+
+#ifdef HAVE_STRERROR
+/* a thread-safe version of strerror */
+const char* strerror_ts (int errnum, struct gc_arena *gc);
+#endif
+
+/* Set standard file descriptors to /dev/null */
+void set_std_files_to_null (bool stdin_only);
+
+/* Wrapper for chdir library function */
+int openvpn_chdir (const char* dir);
+
+/* dup inetd/xinetd socket descriptor and save */
+extern int inetd_socket_descriptor;
+void save_inetd_socket_descriptor (void);
+
+/* init random() function, only used as source for weak random numbers, when !USE_CRYPTO */
+void init_random_seed(void);
+
+/* set/delete environmental variable */
+void setenv_str_ex (struct env_set *es,
+ const char *name,
+ const char *value,
+ const unsigned int name_include,
+ const unsigned int name_exclude,
+ const char name_replace,
+ const unsigned int value_include,
+ const unsigned int value_exclude,
+ const char value_replace);
+
+void setenv_counter (struct env_set *es, const char *name, counter_type value);
+void setenv_int (struct env_set *es, const char *name, int value);
+void setenv_str (struct env_set *es, const char *name, const char *value);
+void setenv_del (struct env_set *es, const char *name);
+
+/* struct env_set functions */
+
+struct env_set *env_set_create (struct gc_arena *gc);
+bool env_set_del (struct env_set *es, const char *str);
+void env_set_add (struct env_set *es, const char *str);
+
+void env_set_print (int msglevel, const struct env_set *es);
+
+void env_set_inherit (struct env_set *es, const struct env_set *src);
+
+void env_set_add_to_environment (const struct env_set *es);
+void env_set_remove_from_environment (const struct env_set *es);
+
+/* Make arrays of strings */
+
+const char **make_env_array (const struct env_set *es, struct gc_arena *gc);
+const char **make_arg_array (const char *first, const char *parms, struct gc_arena *gc);
+
+/* convert netmasks for iproute2 */
+int count_netmask_bits(const char *);
+unsigned int count_bits(unsigned int );
+
+/* go to sleep for n milliseconds */
+void sleep_milliseconds (unsigned int n);
+
+/* go to sleep indefinitely */
+void sleep_until_signal (void);
+
+/* an analogue to the random() function, but use OpenSSL functions if available */
+#ifdef USE_CRYPTO
+long int get_random(void);
+#else
+#define get_random random
+#endif
+
+/* return true if filename can be opened for read */
+bool test_file (const char *filename);
+
+/* create a temporary filename in directory */
+const char *create_temp_filename (const char *directory, struct gc_arena *gc);
+
+/* put a directory and filename together */
+const char *gen_path (const char *directory, const char *filename, struct gc_arena *gc);
+
+/* delete a file, return true if succeeded */
+bool delete_file (const char *filename);
+
+/* return the next largest power of 2 */
+unsigned int adjust_power_of_2 (unsigned int u);
+
+/*
+ * Get and store a username/password
+ */
+
+struct user_pass
+{
+ bool defined;
+ bool nocache;
+
+/* max length of username/password */
+# define USER_PASS_LEN 128
+ char username[USER_PASS_LEN];
+ char password[USER_PASS_LEN];
+};
+
+bool get_console_input (const char *prompt, const bool echo, char *input, const int capacity);
+
+#define GET_USER_PASS_MANAGEMENT (1<<0)
+#define GET_USER_PASS_SENSITIVE (1<<1)
+
+void get_user_pass (struct user_pass *up,
+ const char *auth_file,
+ const bool password_only,
+ const char *prefix,
+ const unsigned int flags);
+
+void purge_user_pass (struct user_pass *up, const bool force);
+
+/*
+ * Process string received by untrusted peer before
+ * printing to console or log file.
+ * Assumes that string has been null terminated.
+ */
+const char *safe_print (const char *str, struct gc_arena *gc);
+
+/*
+ * A sleep function that services the management layer for n
+ * seconds rather than doing nothing.
+ */
+void openvpn_sleep (const int n);
+
+#endif
diff --git a/openvpn/mtu.h b/openvpn/mtu.h
new file mode 100644
index 0000000..3c53a26
--- /dev/null
+++ b/openvpn/mtu.h
@@ -0,0 +1,304 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 MTU_H
+#define MTU_H
+
+#include "buffer.h"
+
+/*
+ *
+ * Packet maninipulation routes such as encrypt, decrypt, compress, decompress
+ * are passed a frame buffer that looks like this:
+ *
+ * [extra_frame bytes] [mtu bytes] [extra_frame_bytes] [compression overflow bytes]
+ * ^
+ * Pointer passed to function points here so that routine
+ * can make use of extra_frame bytes before pointer
+ * to prepend headers, etc.
+ *
+ * extra_frame bytes is large enough for all encryption related overhead.
+ *
+ * mtu bytes will be the MTU size set in the ifconfig statement that configures
+ * the TUN or TAP device such as:
+ *
+ * ifconfig $1 10.1.0.2 pointopoint 10.1.0.1 mtu 1450
+ *
+ * Compression overflow bytes is the worst-case size expansion that would be
+ * expected if we tried to compress mtu + extra_frame bytes of uncompressible data.
+ */
+
+/*
+ * Standard ethernet MTU
+ */
+#define ETHERNET_MTU 1500
+
+/*
+ * It is a fatal error if mtu is less than
+ * this value for tun device.
+ */
+#define TUN_MTU_MIN 100
+
+/*
+ * Default MTU of network over which tunnel data will pass by TCP/UDP.
+ */
+#define LINK_MTU_DEFAULT 1500
+
+/*
+ * Default MTU of tunnel device.
+ */
+#define TUN_MTU_DEFAULT 1500
+
+/*
+ * MTU Defaults for TAP devices
+ */
+#define TAP_MTU_EXTRA_DEFAULT 32
+
+/*
+ * Default MSSFIX value, used for reducing TCP MTU size
+ */
+#define MSSFIX_DEFAULT 1450
+
+/*
+ * Alignment of payload data such as IP packet or
+ * ethernet frame.
+ */
+#define PAYLOAD_ALIGN 4
+
+struct frame {
+ /*
+ * Maximum datagram size to be sent over the tunnel TCP/UDP channel.
+ */
+ int link_mtu;
+ int link_mtu_dynamic;
+
+ /*
+ * How many extra bytes might each subsystem (crypto, TLS, or, compression)
+ * add to frame in worst case?
+ *
+ * mtu + extra_frame = MTU of TCP/UDP transport
+ */
+ int extra_frame;
+
+ /*
+ * Worst case size added to internal buffer due to functions
+ * such as compression which can potentially expand the size of uncompressible
+ * data.
+ */
+ int extra_buffer;
+
+ /*
+ * Max number of bytes in excess of tun mtu size that we might read
+ * or write from TUN/TAP device.
+ */
+ int extra_tun;
+
+ /*
+ * Max number of bytes in excess of link mtu size that we might read
+ * or write from UDP/TCP link.
+ */
+ int extra_link;
+
+ /*
+ * Alignment control
+ */
+# define FRAME_HEADROOM_MARKER_DECRYPT (1<<0)
+# define FRAME_HEADROOM_MARKER_FRAGMENT (1<<1)
+# define FRAME_HEADROOM_MARKER_READ_LINK (1<<2)
+# define FRAME_HEADROOM_MARKER_READ_STREAM (1<<3)
+ unsigned int align_flags;
+ int align_adjust;
+};
+
+/* Routines which read struct frame should use the macros below */
+
+/*
+ * Overhead added to packet payload due to encapsulation
+ */
+#define EXTRA_FRAME(f) ((f)->extra_frame)
+
+/*
+ * Delta between tun payload size and final TCP/UDP datagram size
+ * (not including extra_link additions)
+ */
+#define TUN_LINK_DELTA(f) ((f)->extra_frame + (f)->extra_tun)
+
+/*
+ * This is the size to "ifconfig" the tun or tap device.
+ */
+#define TUN_MTU_SIZE(f) ((f)->link_mtu - TUN_LINK_DELTA(f))
+#define TUN_MTU_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - TUN_LINK_DELTA(f))
+
+/*
+ * This is the maximum packet size that we need to be able to
+ * read from or write to a tun or tap device. For example,
+ * a tap device ifconfiged to an MTU of 1200 might actually want
+ * to return a packet size of 1214 on a read().
+ */
+#define PAYLOAD_SIZE(f) ((f)->link_mtu - (f)->extra_frame)
+#define PAYLOAD_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - (f)->extra_frame)
+
+/*
+ * Max size of a payload packet after encryption, compression, etc.
+ * overhead is added.
+ */
+#define EXPANDED_SIZE(f) ((f)->link_mtu)
+#define EXPANDED_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic)
+#define EXPANDED_SIZE_MIN(f) (TUN_MTU_MIN + TUN_LINK_DELTA(f))
+
+/*
+ * These values are used as maximum size constraints
+ * on read() or write() from TUN/TAP device or TCP/UDP port.
+ */
+#define MAX_RW_SIZE_TUN(f) (PAYLOAD_SIZE(f))
+#define MAX_RW_SIZE_LINK(f) (EXPANDED_SIZE(f) + (f)->extra_link)
+
+/*
+ * Control buffer headroom allocations to allow for efficient prepending.
+ */
+#define FRAME_HEADROOM_BASE(f) (TUN_LINK_DELTA(f) + (f)->extra_buffer + (f)->extra_link)
+#define FRAME_HEADROOM(f) frame_headroom(f, 0)
+#define FRAME_HEADROOM_ADJ(f, fm) frame_headroom(f, fm)
+
+/*
+ * Max size of a buffer used to build a packet for output to
+ * the TCP/UDP port.
+ */
+#define BUF_SIZE(f) (TUN_MTU_SIZE(f) + FRAME_HEADROOM_BASE(f) * 2)
+
+/*
+ * Function prototypes.
+ */
+
+void frame_finalize (struct frame *frame,
+ bool link_mtu_defined,
+ int link_mtu,
+ bool tun_mtu_defined,
+ int tun_mtu);
+
+void frame_subtract_extra (struct frame *frame, const struct frame *src);
+
+void frame_print (const struct frame *frame,
+ int level,
+ const char *prefix);
+
+void set_mtu_discover_type (int sd, int mtu_type);
+int translate_mtu_discover_type_name (const char *name);
+
+/*
+ * frame_set_mtu_dynamic and flags
+ */
+
+#define SET_MTU_TUN (1<<0) /* use tun/tap rather than link sizing */
+#define SET_MTU_UPPER_BOUND (1<<1) /* only decrease dynamic MTU */
+
+void frame_set_mtu_dynamic (struct frame *frame, int mtu, unsigned int flags);
+
+/*
+ * allocate a buffer for socket or tun layer
+ */
+void alloc_buf_sock_tun (struct buffer *buf,
+ const struct frame *frame,
+ const bool tuntap_buffer,
+ const unsigned int align_mask);
+
+/*
+ * EXTENDED_SOCKET_ERROR_CAPABILITY functions -- print extra error info
+ * on socket errors, such as PMTU size. As of 2003.05.11, only works
+ * on Linux 2.4+.
+ */
+
+#if EXTENDED_SOCKET_ERROR_CAPABILITY
+
+void set_sock_extended_error_passing (int sd);
+const char *format_extended_socket_error (int fd, int *mtu, struct gc_arena *gc);
+
+#endif
+
+/*
+ * Calculate a starting offset into a buffer object, dealing with
+ * headroom and alignment issues.
+ */
+static inline int
+frame_headroom (const struct frame *f, const unsigned int flag_mask)
+{
+ const int offset = FRAME_HEADROOM_BASE (f);
+ const int adjust = (flag_mask & f->align_flags) ? f->align_adjust : 0;
+ const int delta = ((PAYLOAD_ALIGN << 24) - (offset + adjust)) & (PAYLOAD_ALIGN - 1);
+ return offset + delta;
+}
+
+/*
+ * frame member adjustment functions
+ */
+
+static inline void
+frame_add_to_extra_frame (struct frame *frame, const int increment)
+{
+ frame->extra_frame += increment;
+}
+
+static inline void
+frame_add_to_extra_tun (struct frame *frame, const int increment)
+{
+ frame->extra_tun += increment;
+}
+
+static inline void
+frame_add_to_extra_link (struct frame *frame, const int increment)
+{
+ frame->extra_link += increment;
+}
+
+static inline void
+frame_add_to_extra_buffer (struct frame *frame, const int increment)
+{
+ frame->extra_buffer += increment;
+}
+
+static inline void
+frame_add_to_align_adjust (struct frame *frame, const int increment)
+{
+ frame->align_adjust += increment;
+}
+
+static inline void
+frame_align_to_extra_frame (struct frame *frame)
+{
+ frame->align_adjust = frame->extra_frame + frame->extra_link;
+}
+
+static inline void
+frame_or_align_flags (struct frame *frame, const unsigned int flag_mask)
+{
+ frame->align_flags |= flag_mask;
+}
+
+static inline bool
+frame_defined (const struct frame *frame)
+{
+ return frame->link_mtu > 0;
+}
+
+#endif
diff --git a/openvpn/otime.h b/openvpn/otime.h
new file mode 100644
index 0000000..974d0af
--- /dev/null
+++ b/openvpn/otime.h
@@ -0,0 +1,206 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 OTIME_H
+#define OTIME_H
+
+#include "common.h"
+#include "integer.h"
+#include "buffer.h"
+#include "thread.h"
+
+struct frequency_limit
+{
+ int max;
+ int per;
+ int n;
+ time_t reset;
+};
+
+struct frequency_limit *frequency_limit_init (int max, int per);
+void frequency_limit_free (struct frequency_limit *f);
+bool frequency_limit_event_allowed (struct frequency_limit *f);
+
+#ifdef WIN32
+int gettimeofday(struct timeval *tv, void *tz);
+#endif
+
+/* format a time_t as ascii, or use current time if 0 */
+const char* time_string (time_t t, int usec, bool show_usec, struct gc_arena *gc);
+
+/* struct timeval functions */
+
+const char *tv_string (const struct timeval *tv, struct gc_arena *gc);
+const char *tv_string_abs (const struct timeval *tv, struct gc_arena *gc);
+
+extern volatile time_t now; /* updated frequently to time(NULL) */
+
+static inline void
+update_time (void)
+{
+ const time_t real_time = time (NULL);
+ if (real_time != now)
+ now = real_time;
+}
+
+static inline void
+tv_clear (struct timeval *tv)
+{
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+}
+
+static inline bool
+tv_defined (const struct timeval *tv)
+{
+ return tv->tv_sec > 0 && tv->tv_usec > 0;
+}
+
+/* return tv1 - tv2 in usec, constrained by max_seconds */
+static inline int
+tv_subtract (const struct timeval *tv1, const struct timeval *tv2, const unsigned int max_seconds)
+{
+ const int max_usec = max_seconds * 1000000;
+ const int sec_diff = tv1->tv_sec - tv2->tv_sec;
+
+ if (sec_diff > ((int)max_seconds + 10))
+ return max_usec;
+ else if (sec_diff < -((int)max_seconds + 10))
+ return -max_usec;
+ return constrain_int (sec_diff * 1000000 + (tv1->tv_usec - tv2->tv_usec), -max_usec, max_usec);
+}
+
+static inline void
+tv_add (struct timeval *dest, const struct timeval *src)
+{
+ dest->tv_sec += src->tv_sec;
+ dest->tv_usec += src->tv_usec;
+ dest->tv_sec += (dest->tv_usec >> 20);
+ dest->tv_usec &= 0x000FFFFF;
+ if (dest->tv_usec >= 1000000)
+ {
+ dest->tv_usec -= 1000000;
+ dest->tv_sec += 1;
+ }
+}
+
+static inline bool
+tv_lt (const struct timeval *t1, const struct timeval *t2)
+{
+ if (t1->tv_sec < t2->tv_sec)
+ return true;
+ else if (t1->tv_sec > t2->tv_sec)
+ return false;
+ else
+ return t1->tv_usec < t2->tv_usec;
+}
+
+static inline bool
+tv_le (const struct timeval *t1, const struct timeval *t2)
+{
+ if (t1->tv_sec < t2->tv_sec)
+ return true;
+ else if (t1->tv_sec > t2->tv_sec)
+ return false;
+ else
+ return t1->tv_usec <= t2->tv_usec;
+}
+
+static inline bool
+tv_ge (const struct timeval *t1, const struct timeval *t2)
+{
+ if (t1->tv_sec > t2->tv_sec)
+ return true;
+ else if (t1->tv_sec < t2->tv_sec)
+ return false;
+ else
+ return t1->tv_usec >= t2->tv_usec;
+}
+
+static inline bool
+tv_gt (const struct timeval *t1, const struct timeval *t2)
+{
+ if (t1->tv_sec > t2->tv_sec)
+ return true;
+ else if (t1->tv_sec < t2->tv_sec)
+ return false;
+ else
+ return t1->tv_usec > t2->tv_usec;
+}
+
+static inline bool
+tv_eq (const struct timeval *t1, const struct timeval *t2)
+{
+ return t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec;
+}
+
+static inline void
+tv_delta (struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
+{
+ int sec = t2->tv_sec - t1->tv_sec;
+ int usec = t2->tv_usec - t1->tv_usec;
+
+ while (usec < 0)
+ {
+ usec += 1000000;
+ sec -= 1;
+ }
+
+ if (sec < 0)
+ usec = sec = 0;
+
+ dest->tv_sec = sec;
+ dest->tv_usec = usec;
+}
+
+#define TV_WITHIN_SIGMA_MAX_SEC 600
+#define TV_WITHIN_SIGMA_MAX_USEC (TV_WITHIN_SIGMA_MAX_SEC * 1000000)
+
+/*
+ * Is t1 and t2 within sigma microseconds of each other?
+ */
+static inline bool
+tv_within_sigma (const struct timeval *t1, const struct timeval *t2, unsigned int sigma)
+{
+ const int delta = tv_subtract (t1, t2, TV_WITHIN_SIGMA_MAX_SEC); /* sigma should be less than 10 minutes */
+ return -(int)sigma <= delta && delta <= (int)sigma;
+}
+
+/*
+ * Used to determine in how many seconds we should be
+ * called again.
+ */
+static inline void
+interval_earliest_wakeup (interval_t *wakeup, time_t at, time_t current) {
+ if (at > current)
+ {
+ const interval_t delta = (interval_t) (at - current);
+ if (delta < *wakeup)
+ *wakeup = delta;
+ if (*wakeup < 0)
+ *wakeup = 0;
+ }
+}
+
+#endif
diff --git a/openvpn/perf.h b/openvpn/perf.h
new file mode 100644
index 0000000..6080886
--- /dev/null
+++ b/openvpn/perf.h
@@ -0,0 +1,82 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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
+ */
+
+/*
+ * The interval_ routines are designed to optimize the calling of a routine
+ * (normally tls_multi_process()) which can be called less frequently
+ * between triggers.
+ */
+
+#ifndef PERF_H
+#define PERF_H
+
+/*#define ENABLE_PERFORMANCE_METRICS*/
+
+/*
+ * Metrics
+ */
+#define PERF_BIO_READ_PLAINTEXT 0
+#define PERF_BIO_WRITE_PLAINTEXT 1
+#define PERF_BIO_READ_CIPHERTEXT 2
+#define PERF_BIO_WRITE_CIPHERTEXT 3
+#define PERF_TLS_MULTI_PROCESS 4
+#define PERF_IO_WAIT 5
+#define PERF_EVENT_LOOP 6
+#define PERF_MULTI_CREATE_INSTANCE 7
+#define PERF_MULTI_CLOSE_INSTANCE 8
+#define PERF_MULTI_SHOW_STATS 9
+#define PERF_MULTI_BCAST 10
+#define PERF_MULTI_MCAST 11
+#define PERF_SCRIPT 12
+#define PERF_READ_IN_LINK 13
+#define PERF_PROC_IN_LINK 14
+#define PERF_READ_IN_TUN 15
+#define PERF_PROC_IN_TUN 16
+#define PERF_PROC_OUT_LINK 17
+#define PERF_PROC_OUT_TUN 18
+#define PERF_PROC_OUT_TUN_MTCP 19
+#define PERF_N 20
+
+#ifdef ENABLE_PERFORMANCE_METRICS
+
+#include "basic.h"
+
+/*
+ * Stack size
+ */
+#define STACK_N 64
+
+void perf_push (int type);
+void perf_pop (void);
+void perf_output_results (void);
+
+#else
+
+static inline void perf_push (int type) {}
+static inline void perf_pop (void) {}
+static inline void perf_output_results (void) {}
+
+#endif
+
+#endif
diff --git a/openvpn/proto.h b/openvpn/proto.h
new file mode 100644
index 0000000..440d3d1
--- /dev/null
+++ b/openvpn/proto.h
@@ -0,0 +1,163 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 PROTO_H
+#define PROTO_H
+
+#include "buffer.h"
+
+/*
+ * Tunnel types
+ */
+#define DEV_TYPE_UNDEF 0
+#define DEV_TYPE_NULL 1
+#define DEV_TYPE_TUN 2 /* point-to-point IP tunnel */
+#define DEV_TYPE_TAP 3 /* ethernet (802.3) tunnel */
+
+/*
+ * IP and Ethernet protocol structs. For portability,
+ * OpenVPN needs its own definitions of these structs, and
+ * names have been adjusted to avoid collisions with
+ * native structs.
+ */
+
+#define OPENVPN_ETH_ALEN 6 /* ethernet address length */
+struct openvpn_ethhdr
+{
+ uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */
+ uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */
+
+# define OPENVPN_ETH_P_IPV4 0x0800 /* IPv4 protocol */
+# define OPENVPN_ETH_P_IPV6 0x86DD /* IPv6 protocol */
+# define OPENVPN_ETH_P_ARP 0x0806 /* ARP protocol */
+ uint16_t proto; /* packet type ID field */
+};
+
+struct openvpn_iphdr {
+# define OPENVPN_IPH_GET_VER(v) (((v) >> 4) & 0x0F)
+# define OPENVPN_IPH_GET_LEN(v) (((v) & 0x0F) << 2)
+ uint8_t version_len;
+
+ uint8_t tos;
+ uint16_t tot_len;
+ uint16_t id;
+
+# define OPENVPN_IP_OFFMASK 0x1fff
+ uint16_t frag_off;
+
+ uint8_t ttl;
+
+# define OPENVPN_IPPROTO_IGMP 2 /* IGMP protocol */
+# define OPENVPN_IPPROTO_TCP 6 /* TCP protocol */
+# define OPENVPN_IPPROTO_UDP 17 /* UDP protocol */
+ uint8_t protocol;
+
+ uint16_t check;
+ uint32_t saddr;
+ uint32_t daddr;
+ /*The options start here. */
+};
+
+/*
+ * UDP header
+ */
+struct openvpn_udphdr {
+ uint16_t source;
+ uint16_t dest;
+ uint16_t len;
+ uint16_t check;
+};
+
+/*
+ * TCP header, per RFC 793.
+ */
+struct openvpn_tcphdr {
+ uint16_t source; /* source port */
+ uint16_t dest; /* destination port */
+ uint32_t seq; /* sequence number */
+ uint32_t ack_seq; /* acknowledgement number */
+
+# define OPENVPN_TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
+ uint8_t doff_res;
+
+# define OPENVPN_TCPH_FIN_MASK (1<<0)
+# define OPENVPN_TCPH_SYN_MASK (1<<1)
+# define OPENVPN_TCPH_RST_MASK (1<<2)
+# define OPENVPN_TCPH_PSH_MASK (1<<3)
+# define OPENVPN_TCPH_ACK_MASK (1<<4)
+# define OPENVPN_TCPH_URG_MASK (1<<5)
+# define OPENVPN_TCPH_ECE_MASK (1<<6)
+# define OPENVPN_TCPH_CWR_MASK (1<<7)
+ uint8_t flags;
+
+ uint16_t window;
+ uint16_t check;
+ uint16_t urg_ptr;
+};
+
+#define OPENVPN_TCPOPT_EOL 0
+#define OPENVPN_TCPOPT_NOP 1
+#define OPENVPN_TCPOPT_MAXSEG 2
+#define OPENVPN_TCPOLEN_MAXSEG 4
+
+/*
+ * The following macro is used to update an
+ * internet checksum. "acc" is a 32-bit
+ * accumulation of all the changes to the
+ * checksum (adding in old 16-bit words and
+ * subtracting out new words), and "cksum"
+ * is the checksum value to be updated.
+ */
+#define ADJUST_CHECKSUM(acc, cksum) { \
+ (acc) += (cksum); \
+ if ((acc) < 0) { \
+ (acc) = -(acc); \
+ (acc) = ((acc) >> 16) + ((acc) & 0xffff); \
+ (acc) += (acc) >> 16; \
+ (cksum) = (uint16_t) ~(acc); \
+ } else { \
+ (acc) = ((acc) >> 16) + ((acc) & 0xffff); \
+ (acc) += (acc) >> 16; \
+ (cksum) = (uint16_t) (acc); \
+ } \
+}
+
+/*
+ * We are in a "liberal" position with respect to MSS,
+ * i.e. we assume that MSS can be calculated from MTU
+ * by subtracting out only the IP and TCP header sizes
+ * without options.
+ *
+ * (RFC 879, section 7).
+ */
+#define MTU_TO_MSS(mtu) (mtu - sizeof(struct openvpn_iphdr) \
+ - sizeof(struct openvpn_tcphdr))
+
+/*
+ * If raw tunnel packet is IPv4, return true and increment
+ * buffer offset to start of IP header.
+ */
+bool is_ipv4 (int tunnel_type, struct buffer *buf);
+
+#endif
diff --git a/openvpn/sig.h b/openvpn/sig.h
new file mode 100644
index 0000000..dd17c40
--- /dev/null
+++ b/openvpn/sig.h
@@ -0,0 +1,100 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 SIG_H
+#define SIG_H
+
+#include "status.h"
+#include "win32.h"
+
+/*
+ * Signal information, including signal code
+ * and descriptive text.
+ */
+struct signal_info
+{
+ volatile int signal_received;
+ volatile bool hard;
+ const char *signal_text;
+};
+
+#define IS_SIG(c) ((c)->sig->signal_received)
+
+struct context;
+
+extern struct signal_info siginfo_static;
+
+int parse_signal (const char *signame);
+const char *signal_name (const int sig, const bool upper);
+const char *signal_description (const int signum, const char *sigtext);
+void throw_signal (const int signum);
+
+void pre_init_signal_catch (void);
+void post_init_signal_catch (void);
+
+void print_signal (const struct signal_info *si, const char *title, int msglevel);
+void print_status (const struct context *c, struct status_output *so);
+
+void remap_signal (struct context *c);
+
+void signal_restart_status (const struct signal_info *si);
+
+bool process_signal (struct context *c);
+
+#ifdef ENABLE_OCC
+void process_explicit_exit_notification_timer_wakeup (struct context *c);
+#endif
+
+#ifdef WIN32
+
+static inline void
+get_signal (volatile int *sig)
+{
+ *sig = win32_signal_get (&win32_signal);
+}
+
+static inline void
+halt_non_edge_triggered_signals (void)
+{
+ win32_signal_close (&win32_signal);
+}
+
+#else
+
+static inline void
+get_signal (volatile int *sig)
+{
+ const int i = siginfo_static.signal_received;
+ if (i)
+ *sig = i;
+}
+
+static inline void
+halt_non_edge_triggered_signals (void)
+{
+}
+
+#endif
+
+#endif
diff --git a/openvpn/status.h b/openvpn/status.h
new file mode 100644
index 0000000..be3c3f3
--- /dev/null
+++ b/openvpn/status.h
@@ -0,0 +1,95 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 STATUS_H
+#define STATUS_H
+
+#include "interval.h"
+
+/*
+ * virtual function interface for status output
+ */
+struct virtual_output {
+ void *arg;
+ unsigned int flags_default;
+ void (*func) (void *arg, const unsigned int flags, const char *str);
+};
+
+static inline void
+virtual_output_print (const struct virtual_output *vo, const unsigned int flags, const char *str)
+{
+ (*vo->func) (vo->arg, flags, str);
+}
+
+/*
+ * printf-style interface for inputting/outputting status info
+ */
+
+struct status_output
+{
+# define STATUS_OUTPUT_READ (1<<0)
+# define STATUS_OUTPUT_WRITE (1<<1)
+ unsigned int flags;
+
+ char *filename;
+ int fd;
+ int msglevel;
+ const struct virtual_output *vout;
+
+ struct buffer read_buf;
+
+ struct event_timeout et;
+
+ bool errors;
+};
+
+struct status_output *status_open (const char *filename,
+ const int refresh_freq,
+ const int msglevel,
+ const struct virtual_output *vout,
+ const unsigned int flags);
+
+bool status_trigger_tv (struct status_output *so, struct timeval *tv);
+bool status_trigger (struct status_output *so);
+void status_reset (struct status_output *so);
+void status_flush (struct status_output *so);
+bool status_close (struct status_output *so);
+void status_printf (struct status_output *so, const char *format, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+
+bool status_read (struct status_output *so, struct buffer *buf);
+
+static inline unsigned int
+status_rw_flags (const struct status_output *so)
+{
+ if (so)
+ return so->flags;
+ else
+ return 0;
+}
+
+#endif
diff --git a/openvpn/thread.h b/openvpn/thread.h
new file mode 100644
index 0000000..ecc3616
--- /dev/null
+++ b/openvpn/thread.h
@@ -0,0 +1,235 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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 THREAD_H
+#define THREAD_H
+
+#include "basic.h"
+#include "common.h"
+
+/*
+ * OpenVPN static mutex locks, by mutex type
+ */
+#define L_UNUSED 0
+#define L_CTIME 1
+#define L_INET_NTOA 2
+#define L_MSG 3
+#define L_STRERR 4
+#define L_PUTENV 5
+#define L_PRNG 6
+#define L_GETTIMEOFDAY 7
+#define L_ENV_SET 8
+#define L_SYSTEM 9
+#define L_CREATE_TEMP 10
+#define L_PLUGIN 11
+#define N_MUTEXES 12
+
+#ifdef USE_PTHREAD
+
+#define MAX_THREADS 50
+
+#define CACHE_LINE_SIZE 128
+
+/*
+ * Improve SMP performance by making sure that each
+ * mutex resides in its own cache line.
+ */
+struct sparse_mutex
+{
+ pthread_mutex_t mutex;
+ uint8_t dummy [CACHE_LINE_SIZE - sizeof (pthread_mutex_t)];
+};
+
+typedef pthread_t openvpn_thread_t;
+
+extern bool pthread_initialized;
+
+extern struct sparse_mutex mutex_array[N_MUTEXES];
+
+#define MUTEX_DEFINE(lock) pthread_mutex_t lock
+#define MUTEX_PTR_DEFINE(lock) pthread_mutex_t *lock
+
+static inline bool
+openvpn_thread_enabled (void)
+{
+ return pthread_initialized;
+}
+
+static inline openvpn_thread_t
+openvpn_thread_self (void)
+{
+ return pthread_initialized ? pthread_self() : 0;
+}
+
+static inline void
+mutex_init (pthread_mutex_t *mutex)
+{
+ if (mutex)
+ pthread_mutex_init (mutex, NULL);
+}
+
+static inline void
+mutex_destroy (pthread_mutex_t *mutex)
+{
+ if (mutex)
+ pthread_mutex_destroy (mutex);
+}
+
+static inline void
+mutex_lock (pthread_mutex_t *mutex)
+{
+ if (pthread_initialized && mutex)
+ pthread_mutex_lock (mutex);
+}
+
+static inline bool
+mutex_trylock (pthread_mutex_t *mutex)
+{
+ if (pthread_initialized && mutex)
+ return pthread_mutex_trylock (mutex) == 0;
+ else
+ return true;
+}
+
+static inline void
+mutex_unlock (pthread_mutex_t *mutex)
+{
+ if (pthread_initialized && mutex)
+ {
+ pthread_mutex_unlock (mutex);
+#if 1 /* JYFIXME: if race conditions exist, make them more likely to occur */
+ sleep (0);
+#endif
+ }
+}
+
+static inline void
+mutex_cycle (pthread_mutex_t *mutex)
+{
+ if (pthread_initialized && mutex)
+ {
+ pthread_mutex_unlock (mutex);
+ sleep (0);
+ pthread_mutex_lock (mutex);
+ }
+}
+
+static inline void
+mutex_lock_static (int type)
+{
+ mutex_lock (&mutex_array[type].mutex);
+}
+
+static inline void
+mutex_unlock_static (int type)
+{
+ mutex_unlock (&mutex_array[type].mutex);
+}
+
+static inline void
+mutex_cycle_static (int type)
+{
+ mutex_cycle (&mutex_array[type].mutex);
+}
+
+void openvpn_thread_init (void);
+void openvpn_thread_cleanup (void);
+
+openvpn_thread_t openvpn_thread_create (void *(*start_routine) (void *), void* arg);
+void openvpn_thread_join (openvpn_thread_t id);
+
+#else /* USE_PTHREAD */
+
+typedef int openvpn_thread_t;
+
+#if defined(_MSC_VER) || PEDANTIC
+
+#define MUTEX_DEFINE(lock) int eat_semicolon
+#define MUTEX_PTR_DEFINE(lock) int eat_semicolon
+
+#else
+
+#define MUTEX_DEFINE(lock)
+#define MUTEX_PTR_DEFINE(lock)
+
+#endif
+
+#define mutex_init(m)
+#define mutex_destroy(m)
+#define mutex_lock(m)
+#define mutex_trylock(m) (true)
+#define mutex_unlock(m)
+#define mutex_cycle(m)
+
+static inline bool
+openvpn_thread_enabled (void)
+{
+ return false;
+}
+
+static inline openvpn_thread_t
+openvpn_thread_self (void)
+{
+ return 0;
+}
+
+static inline void
+openvpn_thread_init (void)
+{
+}
+
+static inline void
+openvpn_thread_cleanup (void)
+{
+}
+
+static inline openvpn_thread_t
+openvpn_thread_create (void *(*start_routine) (void *), void* arg)
+{
+ return 0;
+}
+
+static inline void
+work_thread_join (openvpn_thread_t id)
+{
+}
+
+static inline void
+mutex_lock_static (int type)
+{
+}
+
+static inline void
+mutex_unlock_static (int type)
+{
+}
+
+static inline void
+mutex_cycle_static (int type)
+{
+}
+
+#endif /* USE_PTHREAD */
+
+#endif /* THREAD_H */
diff --git a/openvpn/win32.h b/openvpn/win32.h
new file mode 100755
index 0000000..12af854
--- /dev/null
+++ b/openvpn/win32.h
@@ -0,0 +1,251 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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
+ */
+
+#ifdef WIN32
+#ifndef OPENVPN_WIN32_H
+#define OPENVPN_WIN32_H
+
+#include "mtu.h"
+
+/*
+ * Win32-specific OpenVPN code, targetted at the mingw
+ * development environment.
+ */
+
+void init_win32 (void);
+void uninit_win32 (void);
+
+void set_pause_exit_win32 (void);
+
+/*
+ * Use keyboard input or events
+ * to simulate incoming signals
+ */
+
+#define SIGUSR1 1
+#define SIGUSR2 2
+#define SIGHUP 3
+#define SIGTERM 4
+#define SIGINT 5
+
+struct security_attributes
+{
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+};
+
+#define HANDLE_DEFINED(h) ((h) != NULL && (h) != INVALID_HANDLE_VALUE)
+
+/*
+ * Save old window title.
+ */
+struct window_title
+{
+ bool saved;
+ char old_window_title [256];
+};
+
+struct rw_handle {
+ HANDLE read;
+ HANDLE write;
+};
+
+/*
+ * Event-based notification of incoming TCP connections
+ */
+
+#define NE32_PERSIST_EVENT (1<<0)
+#define NE32_WRITE_EVENT (1<<1)
+
+static inline bool
+defined_net_event_win32 (const struct rw_handle *event)
+{
+ return event->read != NULL;
+}
+
+void init_net_event_win32 (struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags);
+long reset_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd);
+void close_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd, unsigned int flags);
+
+/*
+ * A stateful variant of the net_event_win32 functions above
+ */
+
+struct net_event_win32
+{
+ struct rw_handle handle;
+ socket_descriptor_t sd;
+ long event_mask;
+};
+
+void net_event_win32_init (struct net_event_win32 *ne);
+void net_event_win32_start (struct net_event_win32 *ne, long network_events, socket_descriptor_t sd);
+void net_event_win32_reset (struct net_event_win32 *ne);
+void net_event_win32_reset_write (struct net_event_win32 *ne);
+void net_event_win32_stop (struct net_event_win32 *ne);
+void net_event_win32_close (struct net_event_win32 *ne);
+
+static bool
+net_event_win32_defined (const struct net_event_win32 *ne)
+{
+ return defined_net_event_win32 (&ne->handle);
+}
+
+static inline struct rw_handle *
+net_event_win32_get_event (struct net_event_win32 *ne)
+{
+ return &ne->handle;
+}
+
+static inline long
+net_event_win32_get_event_mask (const struct net_event_win32 *ne)
+{
+ return ne->event_mask;
+}
+
+static inline void
+net_event_win32_clear_selected_events (struct net_event_win32 *ne, long selected_events)
+{
+ ne->event_mask &= ~selected_events;
+}
+
+/*
+ * Signal handling
+ */
+struct win32_signal {
+# define WSO_MODE_UNDEF 0
+# define WSO_MODE_SERVICE 1
+# define WSO_MODE_CONSOLE 2
+ int mode;
+ struct rw_handle in;
+ DWORD console_mode_save;
+ bool console_mode_save_defined;
+};
+
+extern struct win32_signal win32_signal; /* static/global */
+extern struct window_title window_title; /* static/global */
+
+void win32_signal_clear (struct win32_signal *ws);
+
+/* win32_signal_open startup type */
+#define WSO_NOFORCE 0
+#define WSO_FORCE_SERVICE 1
+#define WSO_FORCE_CONSOLE 2
+
+void win32_signal_open (struct win32_signal *ws,
+ int force, /* set to WSO force parm */
+ const char *exit_event_name,
+ bool exit_event_initial_state);
+
+void win32_signal_close (struct win32_signal *ws);
+
+int win32_signal_get (struct win32_signal *ws);
+
+void win32_pause (struct win32_signal *ws);
+
+/*
+ * Set the text on the window title bar
+ */
+
+void window_title_clear (struct window_title *wt);
+void window_title_save (struct window_title *wt);
+void window_title_restore (const struct window_title *wt);
+void window_title_generate (const char *title);
+
+/*
+ * We try to do all Win32 I/O using overlapped
+ * (i.e. asynchronous) I/O for a performance win.
+ */
+struct overlapped_io {
+# define IOSTATE_INITIAL 0
+# define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */
+# define IOSTATE_IMMEDIATE_RETURN 2 /* I/O function returned immediately without queueing */
+ int iostate;
+ OVERLAPPED overlapped;
+ DWORD size;
+ DWORD flags;
+ int status;
+ bool addr_defined;
+ struct sockaddr_in addr;
+ int addrlen;
+ struct buffer buf_init;
+ struct buffer buf;
+};
+
+void overlapped_io_init (struct overlapped_io *o,
+ const struct frame *frame,
+ BOOL event_state,
+ bool tuntap_buffer);
+
+void overlapped_io_close (struct overlapped_io *o);
+
+static inline bool
+overlapped_io_active (struct overlapped_io *o)
+{
+ return o->iostate == IOSTATE_QUEUED || o->iostate == IOSTATE_IMMEDIATE_RETURN;
+}
+
+char *overlapped_io_state_ascii (const struct overlapped_io *o);
+
+/*
+ * Use to control access to resources that only one
+ * OpenVPN process on a given machine can access at
+ * a given time.
+ */
+
+struct semaphore
+{
+ const char *name;
+ bool locked;
+ HANDLE hand;
+};
+
+void semaphore_clear (struct semaphore *s);
+void semaphore_open (struct semaphore *s, const char *name);
+bool semaphore_lock (struct semaphore *s, int timeout_milliseconds);
+void semaphore_release (struct semaphore *s);
+void semaphore_close (struct semaphore *s);
+
+/*
+ * Special global semaphore used to protect network
+ * shell commands from simultaneous instantiation.
+ *
+ * It seems you can't run more than one instance
+ * of netsh on the same machine at the same time.
+ */
+
+extern struct semaphore netcmd_semaphore;
+void netcmd_semaphore_init (void);
+void netcmd_semaphore_close (void);
+void netcmd_semaphore_lock (void);
+void netcmd_semaphore_release (void);
+
+bool get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity);
+char *getpass (const char *prompt);
+
+/* Set Win32 security attributes structure to allow all access */
+bool init_security_attributes_allow_all (struct security_attributes *obj);
+
+#endif
+#endif