Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added a utility to set the ssl library's MT hooks. #527

Merged
merged 1 commit into from

5 participants

@jimfcarroll
Collaborator

This should fix the MT problems with libraries that use SSL. Namely, libcurl. It sets openssl and/or gcrypt locking hooks. It expects gcrypt to be used only on LINUX like machines.

Currently the Windows implementation is missing (at least) the openssl header file(s).

@WiSo, can you let me know what I need to do to get openssl/crypto.h installed on windows? We apparently already have the dll.

@jimfcarroll
Collaborator

WiSo, sorry about the miss-ping (if you check).

@wsoltys is who I meant. ^^

@wsoltys
Collaborator

hehe, WiSo = wsoltys so you pinged me twice ;)
We're using a precompiled libcurl from here http://www.gknw.de/mirror/curl/win32/old_releases/. Problem is every third party lib can ship it's own version of ssl. If we just have an eye on curl we can take the dev package of the version used by libcurl and put it in our dependency lib. We just have to take this version in future too if we need ssl somewhere else and want to use our dependency system (or bump it if we bump libcurl).
Let me see if I can cook something together today or tomorrow.

@wsoltys
Collaborator

I've added the missing headers but getting unresolved external symbols for _CRYPTO_set_locking_callback and _CRYPTO_set_id_callback. To resolve them I would need the ssl import lib which fits to the ssl dll used by the third party build of libcurl which we don't have.
Do we have the curl locking in windows as well or can we skip this implementation?

@wsoltys
Collaborator

so we don't need any changes on win32. If worth I can change to a newer version of libcurl which uses openssl 1.0.0

@jimfcarroll
Collaborator

If that's the case I'm going to simply add a destructor to clean up the locks then check this in. Is everyone Ok with that?

@ghost

what a bloody mess. pull is fine with me.

@elupus
Collaborator

We should do as done in that ffmpeg commit, only set the thread id for older versions.

@arnova
Collaborator

I'm fine with this. Are you sure this works properly with libcurl-gnutls? I'm not that familar with the internals of this...

@jimfcarroll
Collaborator

@arnova, I copied the code from an example and on my system HAVE_GCRYPT is true and it executes. I'm not sure how else to verify it since it's used indirectly anyway.

@davilla

status on this pull/req ? I've been seeing reports of hangs and bt logs that point to

libcrypto.0.9.8.dylib 0x0276a6b8 lh_insert + 152

@jimfcarroll
Collaborator

I have a code change that includes a simplification and cleanup (previous to this the locks don't get cleaned up) I didn't get a chance to check in this weekend. I'll do it shortly.

@jimfcarroll
Collaborator

Ok, one more review would help.

@jimfcarroll
Collaborator

Ok, I'm putting this in. Please let me know if it addresses the problems we've been seeing.

@jimfcarroll jimfcarroll merged commit f587ca9 into xbmc:master
@tru tru referenced this pull request from a commit in plexinc/plex-home-theater-public
@tru tru Fix playing from remote
Fixes #527, Fixes #521
c46f820
@notspiff notspiff referenced this pull request from a commit in notspiff/kodi-cmake
@davilla davilla [osx] fixed, add missing bit from xbmc/xbmc#527 e698e3e
@notspiff notspiff referenced this pull request from a commit in notspiff/kodi-cmake
@davilla davilla [ios] fixed, add missing bit from xbmc/xbmc#527 eb9e268
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 15, 2011
  1. Added a utility to set the ssl library's MT hooks.

    Jim Carroll authored
This page is out of date. Refresh to see the latest.
View
12 configure.in
@@ -698,6 +698,18 @@ AC_CHECK_HEADER([vorbis/vorbisenc.h],, AC_MSG_ERROR($missing_library))
AC_CHECK_HEADER([libmodplug/modplug.h],, AC_MSG_ERROR($missing_library))
AC_CHECK_HEADER([curl/curl.h],, AC_MSG_ERROR($missing_library))
AC_CHECK_HEADER([FLAC/stream_decoder.h],, AC_MSG_ERROR($missing_library))
+
+# we need to check for the header because if it exists we set the openssl
+# and gcrypt MT callback hooks. This is mostly so that libcurl operates
+# in MT manner correctly.
+AC_CHECK_HEADER([openssl/crypto.h], AC_DEFINE([HAVE_OPENSSL],[1],[Define if we have openssl]),)
+AC_CHECK_HEADER([gcrypt.h], gcrypt_headers_available=yes,gcrypt_headers_available=no)
+if test "$gcrypt_headers_available" = "yes"; then
+ # if we have the headers then we must have the lib
+ AC_CHECK_LIB([gcrypt],[gcry_control],, AC_MSG_ERROR($missing_library))
+ AC_DEFINE([HAVE_GCRYPT],[1],[Define if we have gcrypt])
+fi
+
AC_CHECK_LIB([bz2], [main],, AC_MSG_ERROR($missing_library))
AC_CHECK_LIB([jpeg], [main],, AC_MSG_ERROR($missing_library)) # check for cximage
AC_CHECK_LIB([tiff], [main],, AC_MSG_ERROR($missing_library))
View
124 xbmc/utils/CryptThreading.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2005-2008 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifdef TARGET_WINDOWS
+#error "The threading options for the cryptography libraries don't need to be and shouldn't be set on Windows. Do not include CryptThreading in your windows project."
+#endif
+
+#include "CryptThreading.h"
+#include "threads/Thread.h"
+#include "utils/log.h"
+
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+ #include "config.h"
+#else
+#define HAVE_OPENSSL
+#endif
+
+#ifdef HAVE_OPENSSL
+#include <openssl/crypto.h>
+#endif
+
+#ifdef HAVE_GCRYPT
+#include <gcrypt.h>
+#include <errno.h>
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
+
+/* ========================================================================= */
+/* openssl locking implementation for curl */
+static CCriticalSection* getlock(int index)
+{
+ return g_cryptThreadingInitializer.get_lock(index);
+}
+
+static void lock_callback(int mode, int type, const char* file, int line)
+{
+ if (mode & 0x01 /* CRYPTO_LOCK from openssl/crypto.h */ )
+ getlock(type)->lock();
+ else
+ getlock(type)->unlock();
+}
+
+static unsigned long thread_id()
+{
+ return (unsigned long)CThread::GetCurrentThreadId();
+}
+/* ========================================================================= */
+
+CryptThreadingInitializer::CryptThreadingInitializer()
+{
+ bool attemptedToSetSSLMTHook = false;
+#ifdef HAVE_OPENSSL
+ // set up OpenSSL
+ numlocks = CRYPTO_num_locks();
+ CRYPTO_set_id_callback(thread_id);
+ CRYPTO_set_locking_callback(lock_callback);
+ attemptedToSetSSLMTHook = true;
+#else
+ numlocks = 1;
+#endif
+
+ locks = new CCriticalSection*[numlocks];
+ for (int i = 0; i < numlocks; i++)
+ locks[i] = NULL;
+
+#ifdef HAVE_GCRYPT
+ // set up gcrypt
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ attemptedToSetSSLMTHook = true;
+#endif
+
+ if (!attemptedToSetSSLMTHook)
+ CLog::Log(LOGWARNING, "Could not determine the libcurl security library to set the locking scheme. This may cause problem with multithreaded use of ssl or libraries that depend on it (libcurl).");
+
+}
+
+CryptThreadingInitializer::~CryptThreadingInitializer()
+{
+ CSingleLock l(locksLock);
+#ifdef HAVE_OPENSSL
+ CRYPTO_set_locking_callback(NULL);
+#endif
+
+ for (int i = 0; i < numlocks; i++)
+ delete locks[i]; // I always forget ... delete is NULL safe.
+
+ delete [] locks;
+}
+
+CCriticalSection* CryptThreadingInitializer::get_lock(int index)
+{
+ CSingleLock l(locksLock);
+ CCriticalSection* curlock = locks[index];
+ if (curlock == NULL)
+ {
+ curlock = new CCriticalSection();
+ locks[index] = curlock;
+ }
+
+ return curlock;
+}
+
+
+
+
View
41 xbmc/utils/CryptThreading.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005-2008 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "utils/GlobalsHandling.h"
+#include "threads/CriticalSection.h"
+
+class CryptThreadingInitializer
+{
+ CCriticalSection** locks;
+ int numlocks;
+ CCriticalSection locksLock;
+
+public:
+ CryptThreadingInitializer();
+ ~CryptThreadingInitializer();
+
+ CCriticalSection* get_lock(int index);
+};
+
+XBMC_GLOBAL_REF(CryptThreadingInitializer,g_cryptThreadingInitializer);
+#define g_cryptThreadingInitializer XBMC_GLOBAL_USE(CryptThreadingInitializer)
View
1  xbmc/utils/Makefile
@@ -7,6 +7,7 @@ SRCS=AlarmClock.cpp \
CharsetConverter.cpp \
CPUInfo.cpp \
Crc32.cpp \
+ CryptThreading.cpp \
DownloadQueue.cpp \
DownloadQueueManager.cpp \
Fanart.cpp \
Something went wrong with that request. Please try again.