Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b
Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/main/openssl.c b/src/main/openssl.c
new file mode 100644
index 0000000..dfeb91e
--- /dev/null
+++ b/src/main/openssl.c
@@ -0,0 +1,165 @@
+/**
+ * @file openssl.c OpenSSL initialisation and multi-threading routines
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#ifdef HAVE_SIGNAL
+#include <signal.h>
+#endif
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <re_types.h>
+#include <re_lock.h>
+#include <re_mem.h>
+#include "main.h"
+
+
+#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+
+
+static pthread_mutex_t *lockv;
+
+
+static inline unsigned long threadid(void)
+{
+#if defined (DARWIN) || defined (FREEBSD) || defined (OPENBSD) || \
+ defined (NETBSD) || defined (DRAGONFLY)
+ return (unsigned long)(void *)pthread_self();
+#else
+ return (unsigned long)pthread_self();
+#endif
+}
+
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000
+static void threadid_handler(CRYPTO_THREADID *id)
+{
+ CRYPTO_THREADID_set_numeric(id, threadid());
+}
+#else
+static unsigned long threadid_handler(void)
+{
+ return threadid();
+}
+#endif
+
+
+static void locking_handler(int mode, int type, const char *file, int line)
+{
+ (void)file;
+ (void)line;
+
+ if (mode & CRYPTO_LOCK)
+ (void)pthread_mutex_lock(&lockv[type]);
+ else
+ (void)pthread_mutex_unlock(&lockv[type]);
+}
+
+
+#endif
+
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static struct CRYPTO_dynlock_value *dynlock_create_handler(const char *file,
+ int line)
+{
+ struct lock *lock;
+ (void)file;
+ (void)line;
+
+ if (lock_alloc(&lock))
+ return NULL;
+
+ return (struct CRYPTO_dynlock_value *)lock;
+}
+
+
+static void dynlock_lock_handler(int mode, struct CRYPTO_dynlock_value *l,
+ const char *file, int line)
+{
+ struct lock *lock = (struct lock *)l;
+ (void)file;
+ (void)line;
+
+ if (mode & CRYPTO_LOCK)
+ lock_write_get(lock);
+ else
+ lock_rel(lock);
+}
+
+
+static void dynlock_destroy_handler(struct CRYPTO_dynlock_value *l,
+ const char *file, int line)
+{
+ (void)file;
+ (void)line;
+
+ mem_deref(l);
+}
+#endif
+
+
+#ifdef SIGPIPE
+static void sigpipe_handler(int x)
+{
+ (void)x;
+ (void)signal(SIGPIPE, sigpipe_handler);
+}
+#endif
+
+
+int openssl_init(void)
+{
+#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ int err, i;
+
+ lockv = mem_zalloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks(), NULL);
+ if (!lockv)
+ return ENOMEM;
+
+ for (i=0; i<CRYPTO_num_locks(); i++) {
+
+ err = pthread_mutex_init(&lockv[i], NULL);
+ if (err) {
+ lockv = mem_deref(lockv);
+ return err;
+ }
+ }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000
+ CRYPTO_THREADID_set_callback(threadid_handler);
+#else
+ CRYPTO_set_id_callback(threadid_handler);
+#endif
+
+ CRYPTO_set_locking_callback(locking_handler);
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ CRYPTO_set_dynlock_create_callback(dynlock_create_handler);
+ CRYPTO_set_dynlock_lock_callback(dynlock_lock_handler);
+ CRYPTO_set_dynlock_destroy_callback(dynlock_destroy_handler);
+#endif
+
+#ifdef SIGPIPE
+ (void)signal(SIGPIPE, sigpipe_handler);
+#endif
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ return 0;
+}
+
+
+void openssl_close(void)
+{
+ ERR_free_strings();
+#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ lockv = mem_deref(lockv);
+#endif
+}