summaryrefslogtreecommitdiff
path: root/src/libstrongswan/utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils.h')
-rw-r--r--src/libstrongswan/utils.h99
1 files changed, 90 insertions, 9 deletions
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
index a334954ae..cedfe8fd1 100644
--- a/src/libstrongswan/utils.h
+++ b/src/libstrongswan/utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2011 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -121,8 +121,9 @@
/**
* Object allocation/initialization macro, using designated initializer.
*/
-#define INIT(this, ...) { (this) = malloc(sizeof(*this)); \
- *(this) = (typeof(*this)){ __VA_ARGS__ }; }
+#define INIT(this, ...) ({ (this) = malloc(sizeof(*(this))); \
+ *(this) = (typeof(*(this))){ __VA_ARGS__ }; \
+ (this); })
/**
* Method declaration/definition macro, providing private and public interface.
@@ -347,17 +348,20 @@ void memwipe_noinline(void *ptr, size_t n);
static inline void memwipe_inline(void *ptr, size_t n)
{
volatile char *c = (volatile char*)ptr;
- int m, i;
+ size_t m, i;
/* byte wise until long aligned */
- for (i = 0; (uintptr_t)&c % sizeof(long) && i < n; i++)
+ for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
{
c[i] = 0;
}
- /* word wize */
- for (m = n - sizeof(long); i <= m; i += sizeof(long))
+ /* word wise */
+ if (n >= sizeof(long))
{
- *(volatile long*)&c[i] = 0;
+ for (m = n - sizeof(long); i <= m; i += sizeof(long))
+ {
+ *(volatile long*)&c[i] = 0;
+ }
}
/* byte wise of the rest */
for (; i < n; i++)
@@ -404,6 +408,15 @@ char *translate(char *str, const char *from, const char *to);
*/
bool mkdir_p(const char *path, mode_t mode);
+#ifndef HAVE_CLOSEFROM
+/**
+ * Close open file descriptors greater than or equal to lowfd.
+ *
+ * @param lowfd start closing file descriptoros from here
+ */
+void closefrom(int lowfd);
+#endif
+
/**
* Get a timestamp from a monotonic time source.
*
@@ -470,6 +483,27 @@ static inline void htoun32(void *network, u_int32_t host)
}
/**
+ * Write a 64-bit host order value in network order to an unaligned address.
+ *
+ * @param host host order 64-bit value
+ * @param network unaligned address to write network order value to
+ */
+static inline void htoun64(void *network, u_int64_t host)
+{
+ char *unaligned = (char*)network;
+ u_int32_t high_part, low_part;
+
+ high_part = host >> 32;
+ high_part = htonl(high_part);
+ low_part = host & 0xFFFFFFFFLL;
+ low_part = htonl(low_part);
+
+ memcpy(unaligned, &high_part, sizeof(high_part));
+ unaligned += sizeof(high_part);
+ memcpy(unaligned, &low_part, sizeof(low_part));
+}
+
+/**
* Read a 16-bit value in network order from an unaligned address to host order.
*
* @param network unaligned address to read network order value from
@@ -500,6 +534,27 @@ static inline u_int32_t untoh32(void *network)
}
/**
+ * Read a 64-bit value in network order from an unaligned address to host order.
+ *
+ * @param network unaligned address to read network order value from
+ * @return host order value
+ */
+static inline u_int64_t untoh64(void *network)
+{
+ char *unaligned = (char*)network;
+ u_int32_t high_part, low_part;
+
+ memcpy(&high_part, unaligned, sizeof(high_part));
+ unaligned += sizeof(high_part);
+ memcpy(&low_part, unaligned, sizeof(low_part));
+
+ high_part = ntohl(high_part);
+ low_part = ntohl(low_part);
+
+ return (((u_int64_t)high_part) << 32) + low_part;
+}
+
+/**
* Special type to count references
*/
typedef volatile u_int refcount_t;
@@ -510,6 +565,11 @@ typedef volatile u_int refcount_t;
#define ref_get(ref) {__sync_fetch_and_add(ref, 1); }
#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
+#define cas_bool(ptr, oldval, newval) \
+ (__sync_bool_compare_and_swap(ptr, oldval, newval))
+#define cas_ptr(ptr, oldval, newval) \
+ (__sync_bool_compare_and_swap(ptr, oldval, newval))
+
#else /* !HAVE_GCC_ATOMIC_OPERATIONS */
/**
@@ -532,6 +592,27 @@ void ref_get(refcount_t *ref);
*/
bool ref_put(refcount_t *ref);
+/**
+ * Atomically replace value of ptr with newval if it currently equals oldval.
+ *
+ * @param ptr pointer to variable
+ * @param oldval old value of the variable
+ * @param newval new value set if possible
+ * @return TRUE if value equaled oldval and newval was written
+ */
+bool cas_bool(bool *ptr, bool oldval, bool newval);
+
+/**
+ * Atomically replace value of ptr with newval if it currently equals oldval.
+ *
+ * @param ptr pointer to variable
+ * @param oldval old value of the variable
+ * @param newval new value set if possible
+ * @return TRUE if value equaled oldval and newval was written
+ */
+bool cas_ptr(void **ptr, void *oldval, void *newval);
+
+
#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
/**
@@ -556,7 +637,7 @@ int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
* printf hook for memory areas.
*
* Arguments are:
- * u_char *ptr, int len
+ * u_char *ptr, u_int len
*/
int mem_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
const void *const *args);