aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-07-16 20:36:54 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-07-16 20:36:54 +0000
commit5d89a3629cb0fd0ca6764ba9a6d6e3d1ff61c70b (patch)
treed16a1846265310a31d8aa02c3276306240772ce8
parentCopyright change OpenVPN Solutions LLC -> Telethra, Inc. (diff)
downloadopenvpn-5d89a3629cb0fd0ca6764ba9a6d6e3d1ff61c70b.tar.xz
Added likely() and unlikely() branch prediction hint macros
to syshead.h Introduced BUF_MAX constant to limit struct buffer offset and length values. BUF_MAX has been set to 2^20. Use likely() and unlikely() macros in buffer.h code to allow the compiler to generate more efficient code. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3058 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--buffer.c1
-rw-r--r--buffer.h77
-rw-r--r--syshead.h9
-rw-r--r--version.m42
4 files changed, 68 insertions, 21 deletions
diff --git a/buffer.c b/buffer.c
index 03ff8fc..08f0656 100644
--- a/buffer.c
+++ b/buffer.c
@@ -54,6 +54,7 @@ alloc_buf_gc (size_t size, struct gc_arena *gc)
#endif
{
struct buffer buf;
+ ASSERT (size <= BUF_MAX);
buf.capacity = (int)size;
buf.offset = 0;
buf.len = 0;
diff --git a/buffer.h b/buffer.h
index 4c435e4..a870e2f 100644
--- a/buffer.h
+++ b/buffer.h
@@ -43,6 +43,8 @@
/* basic buffer class for OpenVPN */
+#define BUF_MAX (1<<20) /* maximum allowed size of struct buffer offset and len */
+
struct buffer
{
int capacity; /* size of buffer allocated by malloc */
@@ -147,7 +149,10 @@ buf_reset_len (struct buffer *buf)
static inline bool
buf_init_dowork (struct buffer *buf, int offset)
{
- if (offset < 0 || offset > buf->capacity || buf->data == NULL)
+ if (unlikely (offset < 0)
+ || unlikely (offset > buf->capacity)
+ || unlikely (offset > BUF_MAX)
+ || unlikely (buf->data == NULL))
return false;
buf->len = 0;
buf->offset = offset;
@@ -174,6 +179,8 @@ buf_set_write (struct buffer *buf, uint8_t *data, int size)
static inline void
buf_set_read (struct buffer *buf, const uint8_t *data, int size)
{
+ if (unlikely(size > BUF_MAX))
+ size = 0;
buf->len = buf->capacity = size;
buf->offset = 0;
buf->data = (uint8_t *)data;
@@ -283,32 +290,50 @@ struct buffer buf_sub (struct buffer *buf, int size, bool prepend);
static inline bool
buf_safe (const struct buffer *buf, int len)
{
- return len >= 0 && buf->offset + buf->len + len <= buf->capacity;
+ if (unlikely(buf->offset > BUF_MAX) || unlikely(buf->len) > BUF_MAX || unlikely(len > BUF_MAX))
+ return false;
+ else
+ return likely(len >= 0) && likely(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;
+ if (unlikely(buf->offset > BUF_MAX) || unlikely(buf->len) > BUF_MAX || unlikely(len > BUF_MAX))
+ return false;
+ else
+ {
+ const int newlen = buf->len + len;
+ return likely(newlen >= 0) && likely(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;
+ if (unlikely(buf->offset > BUF_MAX) || unlikely(buf->len) > BUF_MAX)
+ return 0;
+ else
+ {
+ 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;
+ if (unlikely(buf->offset > BUF_MAX))
+ return 0;
+ else
+ {
+ int ret = buf->capacity - buf->offset;
+ if (ret < 0)
+ ret = 0;
+ return ret;
+ }
}
static inline int
@@ -320,7 +345,7 @@ buf_reverse_capacity (const struct buffer *buf)
static inline bool
buf_inc_len (struct buffer *buf, int inc)
{
- if (!buf_safe_bidir (buf, inc))
+ if (unlikely(!buf_safe_bidir (buf, inc)))
return false;
buf->len += inc;
return true;
@@ -334,7 +359,11 @@ buf_inc_len (struct buffer *buf, int inc)
static inline uint8_t *
buf_prepend (struct buffer *buf, int size)
{
- if (size < 0 || size > buf->offset)
+ if (unlikely(size < 0)
+ || unlikely(size > buf->offset)
+ || unlikely(size > BUF_MAX)
+ || unlikely(buf->offset > BUF_MAX)
+ || unlikely(buf->len > BUF_MAX))
return NULL;
buf->offset -= size;
buf->len += size;
@@ -344,7 +373,11 @@ buf_prepend (struct buffer *buf, int size)
static inline bool
buf_advance (struct buffer *buf, int size)
{
- if (size < 0 || buf->len < size)
+ if (unlikely(size < 0)
+ || unlikely(buf->len < size)
+ || unlikely(size > BUF_MAX)
+ || unlikely(buf->offset > BUF_MAX)
+ || unlikely(buf->len > BUF_MAX))
return false;
buf->offset += size;
buf->len -= size;
@@ -448,11 +481,15 @@ buf_copy_range (struct buffer *dest,
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)
+ if (unlikely(src_index < 0)
+ || unlikely(src_len < 0)
+ || unlikely(src_index > BUF_MAX)
+ || unlikely(src_len > BUF_MAX)
+ || unlikely(dest->offset > BUF_MAX)
+ || unlikely(dest_index > BUF_MAX)
+ || unlikely(src_index + src_len > src->len)
+ || unlikely(dest_index < 0)
+ || unlikely(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)
diff --git a/syshead.h b/syshead.h
index e6ced2a..07f1970 100644
--- a/syshead.h
+++ b/syshead.h
@@ -36,6 +36,15 @@
#endif
#endif
+/* branch prediction hints */
+#if defined(__GNUC__)
+# define likely(x) __builtin_expect((x),1)
+# define unlikely(x) __builtin_expect((x),0)
+#else
+# define likely(x) (x)
+# define unlikely(x) (x)
+#endif
+
#if defined(_WIN32) && !defined(WIN32)
#define WIN32
#endif
diff --git a/version.m4 b/version.m4
index 2c4bb6a..7c0b987 100644
--- a/version.m4
+++ b/version.m4
@@ -1,5 +1,5 @@
dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1_rc8])
+define(PRODUCT_VERSION,[2.1_rc8a])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])