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
+}