Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

apparently, libcurl does require some extra effort to make the underl…

…ying SSL implementations thread-safe.
  • Loading branch information...
commit baccb0aee890c966617cb2f4191b30ac9fb68dde 1 parent 3aa2da2
@akrennmair authored
View
9 config.sh
@@ -73,6 +73,14 @@ all_aboard_the_fail_boat() {
fi
}
+check_ssl_implementation() {
+ if curl-config --static-libs | grep -- -lssl > /dev/null 2>&1 ; then
+ echo "DEFINES+=-DHAVE_OPENSSL=1" >> config.mk
+ elif curl-config --static-libs | grep -- -lgcrypt > /dev/null 2>&1 ; then
+ echo "DEFINES+=-DHAVE_GCRYPT=1" >> config.mk
+ fi
+}
+
echo "" > config.mk
check_pkg "sqlite3" || fail "sqlite3"
@@ -80,3 +88,4 @@ check_pkg "libcurl" || check_custom "libcurl" "curl-config" || fail "libcurl"
check_pkg "libxml-2.0" || check_custom "libxml2" "xml2-config" || fail "libxml2"
check_pkg "stfl" "" "--static" || fail "stfl"
all_aboard_the_fail_boat
+check_ssl_implementation
View
1  include/utils.h
@@ -92,6 +92,7 @@ class utils {
static std::string escape_url(const std::string& url);
static std::string unescape_url(const std::string& url);
+ static void initialize_ssl_implementation(void);
private:
static void append_escapes(std::string& str, char c);
View
1  newsbeuter.cpp
@@ -12,6 +12,7 @@
using namespace newsbeuter;
int main(int argc, char * argv[]) {
+ utils::initialize_ssl_implementation();
if (!setlocale(LC_CTYPE,"") || !setlocale(LC_MESSAGES,"")) {
std::cerr << "setlocale failed: " << strerror(errno) << std::endl;
View
2  podbeuter.cpp
@@ -5,10 +5,12 @@
#include <cstring>
#include <pb_view.h>
#include <errno.h>
+#include <utils.h>
using namespace podbeuter;
int main(int argc, char * argv[]) {
+ utils::initialize_ssl_implementation();
if (!setlocale(LC_CTYPE,"") || !setlocale(LC_MESSAGES,"")) {
std::cerr << "setlocale failed: " << strerror(errno) << std::endl;
View
53 src/utils.cpp
@@ -24,6 +24,18 @@
#include <stfl.h>
#include <libxml/uri.h>
+#if HAVE_GCRYPT
+#include <gnutls/gnutls.h>
+#include <gcrypt.h>
+#include <errno.h>
+#include <pthread.h>
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
+
+#if HAVE_OPENSSL
+#include <openssl/crypto.h>
+#endif
+
namespace newsbeuter {
std::vector<std::string> utils::tokenize_quoted(const std::string& str, std::string delimiters) {
@@ -881,4 +893,45 @@ std::wstring utils::clean_nonprintable_characters(std::wstring text) {
return text;
}
+/*
+ * See http://curl.haxx.se/libcurl/c/libcurl-tutorial.html#Multi-threading for a reason why we do this.
+ */
+
+#if HAVE_OPENSSL
+static mutex * openssl_mutexes = NULL;
+static int openssl_mutexes_size = 0;
+
+static void openssl_mth_locking_function(int mode, int n, const char * file, int line) {
+ if (n < 0 || n >= openssl_mutexes_size) {
+ LOG(LOG_ERROR,"openssl_mth_locking_function: index is out of bounds (called by %s:%d)", file, line);
+ return;
+ }
+ if (mode & CRYPTO_LOCK) {
+ LOG(LOG_DEBUG, "OpenSSL lock %d: %s:%d", n, file, line);
+ openssl_mutexes[n].lock();
+ } else {
+ LOG(LOG_DEBUG, "OpenSSL unlock %d: %s:%d", n, file, line);
+ openssl_mutexes[n].unlock();
+ }
+}
+
+static unsigned long openssl_mth_id_function(void) {
+ return (unsigned long)pthread_self();
+}
+#endif
+
+void utils::initialize_ssl_implementation(void) {
+#if HAVE_OPENSSL
+ openssl_mutexes_size = CRYPTO_num_locks();
+ openssl_mutexes = new mutex[openssl_mutexes_size];
+ CRYPTO_set_id_callback(openssl_mth_id_function);
+ CRYPTO_set_locking_callback(openssl_mth_locking_function);
+#endif
+
+#if HAVE_GCRYPT
+ gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ gnutls_global_init();
+#endif
+}
+
}
Please sign in to comment.
Something went wrong with that request. Please try again.