Explorar o código

Tell openssl how to use locks and how to find thread ids -- this may prevent race conditions surrounding the error queue.

svn:r3622
Nick Mathewson %!s(int64=20) %!d(string=hai) anos
pai
achega
aac97a3c6a
Modificáronse 3 ficheiros con 44 adicións e 0 borrados
  1. 15 0
      src/common/compat.c
  2. 1 0
      src/common/compat.h
  3. 28 0
      src/common/crypto.c

+ 15 - 0
src/common/compat.c

@@ -72,6 +72,10 @@ const char compat_c_id[] = "$Id$";
 #include "log.h"
 #include "util.h"
 
+#ifdef TOR_IS_MULTITHREADED
+#include <openssl/crypto.h>
+#endif
+
 /* Inline the strl functions if the platform doesn't have them. */
 #ifndef HAVE_STRLCPY
 #include "strlcpy.c"
@@ -774,6 +778,11 @@ void tor_mutex_release(tor_mutex_t *m)
     log_fn(LOG_WARN, "Failed to release mutex: %d", GetLastError());
   }
 }
+unsigned long
+tor_get_thread_id(void)
+{
+  return (unsigned long)GetCurrentThreadId();
+}
 #elif defined(USE_PTHREADS)
 struct tor_mutex_t {
   pthread_mutex_t mutex;
@@ -800,6 +809,11 @@ void tor_mutex_free(tor_mutex_t *m)
   pthread_mutex_destroy(&m->mutex);
   tor_free(m);
 }
+unsigned long
+tor_get_thread_id(void)
+{
+  return (unsigned long)pthread_self();
+}
 #else
 struct tor_mutex_t {
   int _unused;
@@ -808,6 +822,7 @@ tor_mutex_t *tor_mutex_new(void) { return NULL; }
 void tor_mutex_acquire(tor_mutex_t *m) { }
 void tor_mutex_release(tor_mutex_t *m) { }
 void tor_mutex_free(tor_mutex_t *m) { }
+unsigned long tor_get_thread_id(void) { return 1; }
 #endif
 
 /**

+ 1 - 0
src/common/compat.h

@@ -199,6 +199,7 @@ tor_mutex_t *tor_mutex_new(void);
 void tor_mutex_acquire(tor_mutex_t *m);
 void tor_mutex_release(tor_mutex_t *m);
 void tor_mutex_free(tor_mutex_t *m);
+unsigned long tor_get_thread_id(void);
 
 #if defined(MS_WINDOWS)
 #define USE_WIN32_THREADS

+ 28 - 0
src/common/crypto.c

@@ -55,6 +55,7 @@ const char crypto_c_id[] = "$Id$";
 #include "aes.h"
 #include "util.h"
 #include "container.h"
+#include "compat.h"
 
 #if OPENSSL_VERSION_NUMBER < 0x00905000l
 #error "We require openssl >= 0.9.5"
@@ -100,6 +101,8 @@ RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env);
 EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private);
 DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh);
 
+static int setup_openssl_threading(void);
+
 /** Return the number of bytes added by padding method <b>padding</b>.
  */
 static INLINE int
@@ -157,6 +160,7 @@ int crypto_global_init()
   if (!_crypto_global_initialized) {
       ERR_load_crypto_strings();
       _crypto_global_initialized = 1;
+      setup_openssl_threading();
   }
   return 0;
 }
@@ -1626,3 +1630,27 @@ secret_to_key(char *key_out, size_t key_out_len, const char *secret,
   crypto_free_digest_env(d);
 }
 
+#ifdef TOR_IS_MULTITHREADED
+static tor_mutex_t **_openssl_mutexes = NULL;
+static void
+_openssl_locking_cb(int mode, int n, const char *file, int line)
+{
+  if (mode & CRYPTO_LOCK)
+    tor_mutex_acquire(_openssl_mutexes[n]);
+  else
+    tor_mutex_release(_openssl_mutexes[n]);
+}
+static int
+setup_openssl_threading(void) {
+  int i;
+  int n = CRYPTO_num_locks();
+  _openssl_mutexes = tor_malloc(n*sizeof(tor_mutex_t *));
+  for (i=0; i <n; ++i)
+    _openssl_mutexes[i] = tor_mutex_new();
+  CRYPTO_set_locking_callback(_openssl_locking_cb);
+  CRYPTO_set_id_callback(tor_get_thread_id);
+  return 0;
+}
+#else
+static int setup_openssl_threading(void) { return 0; }
+#endif