Of the presented patches, I didn't find one that seemed to actually work, so I wrote one based on those presented. It is attached. Please test it in your environments. I have tested that it passes the basic tls test suite against a threaded Tcl 8.5.7 core build on Linux-x64 (and verified that OPENSSL_THREADS was true for this install).

This patch is against tls 1.6 head.

Jeff

On 05/05/2009 3:42 PM, Sep Ng wrote:
I'll try it.  I didn't give it much thought at first but looking at it
again, I think it might prevent the long string of ns_free and other
calls to free memory after DH_free.

On May 6, 3:43 am, Jeff Hobbs <je...@activestate.com> wrote:
Just starting to look at this, but from the nsopenssl.c I saw another
interesting function not used by TLS:

if (CRYPTO_set_mem_functions(ns_malloc, ns_realloc, ns_free) == 0) ...

We could do the same and point to Tcl_Alloc, Tcl_Realloc and Tcl_Free.
I'm not sure they are necessary, and CRYPTO_set_mem_debug_functions
isn't used, but it might help debug.


--
AOLserver - http://www.aolserver.com/

To Remove yourself from this list, simply send an email to 
<lists...@listserv.aol.com> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: 
field of your email blank.
? announce.txt
? tls-thread.diff
? tls-verify.diff
Index: Makefile.in
===================================================================
RCS file: /cvsroot/tls/tls/Makefile.in,v
retrieving revision 1.27
diff -u -r1.27 Makefile.in
--- Makefile.in 19 Mar 2008 22:57:03 -0000      1.27
+++ Makefile.in 5 May 2009 23:52:38 -0000
@@ -205,7 +205,7 @@
              file copy [file join $(srcdir) tls.tcl] tls.tcl \
          } ;\
          source [file join $(srcdir) tls.tcl]; \
-         set argv $(TESTFLAGS); \
+         set argv {$(TESTFLAGS)}; \
          source [file join $(srcdir) tests all.tcl]" | $(TCLSH)
 
 shell: binaries libraries
Index: tls.c
===================================================================
RCS file: /cvsroot/tls/tls/tls.c,v
retrieving revision 1.30
diff -u -r1.30 tls.c
--- tls.c       19 Mar 2008 22:06:13 -0000      1.30
+++ tls.c       5 May 2009 23:52:38 -0000
@@ -130,6 +130,46 @@
 #define sk_SSL_CIPHER_value( sk, index)        (SSL_CIPHER*)sk_value((sk), 
(index))
 #endif
 
+/*
+ * Thread-Safe TLS Code
+ */
+
+#ifdef TCL_THREADS
+#define OPENSSL_THREAD_DEFINES
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_THREADS
+#include <openssl/crypto.h>
+
+/*
+ * Threaded operation requires locking callbacks
+ * Based from /crypto/cryptlib.c of OpenSSL and NSOpenSSL.
+ */
+
+static Tcl_Mutex locks[CRYPTO_NUM_LOCKS];
+
+static void CryptoThreadLockCallback(int mode, int n,
+       const char *file, int line);
+static unsigned long CryptoThreadIdCallback(void);
+
+static void
+CryptoThreadLockCallback(int mode, int n, const char *file, int line)
+{
+    if (mode & CRYPTO_LOCK) {
+       Tcl_MutexLock(&locks[n]);
+    } else {
+       Tcl_MutexUnlock(&locks[n]);
+    }
+}
+
+static unsigned long
+CryptoThreadIdCallback(void)
+{
+    return (unsigned long) Tcl_GetCurrentThread();
+}
+#endif /* OPENSSL_THREADS */
+#endif /* TCL_THREADS */
+
 
 /*
  *-------------------------------------------------------------------
@@ -1468,6 +1508,9 @@
 {
     int major, minor, patchlevel, release, i;
     char rnd_seed[16] = "GrzSlplKqUdnnzP!";    /* 16 bytes */
+#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
+    size_t num_locks;
+#endif
 
     /*
      * The original 8.2.0 stacked channel implementation (and the patch
@@ -1500,6 +1543,24 @@
        channelTypeVersion = TLS_CHANNEL_VERSION_1;
     }
 
+    if (CRYPTO_set_mem_functions((void *(*)(size_t))Tcl_Alloc,
+                   (void *(*)(void *, size_t))Tcl_Realloc,
+                   (void(*)(void *))Tcl_Free) == 0) {
+       /* Not using Tcl's mem functions ... not critical */
+    }
+
+#if defined(OPENSSL_THREADS) && defined(TCL_THREADS)
+    /* should we consider allocating mutexes? */
+    num_locks = CRYPTO_num_locks();
+    if (num_locks > CRYPTO_NUM_LOCKS) {
+       Tcl_AppendResult(interp, "crypto num locks size error", NULL);
+       return TCL_ERROR;
+    }
+
+    CRYPTO_set_locking_callback(CryptoThreadLockCallback);
+    CRYPTO_set_id_callback(CryptoThreadIdCallback);
+#endif
+
     if (SSL_library_init() != 1) {
        Tcl_AppendResult(interp, "could not initialize SSL library", NULL);
        return TCL_ERROR;


--
AOLserver - http://www.aolserver.com/

To Remove yourself from this list, simply send an email to 
<lists...@listserv.aol.com> with the
body of "SIGNOFF AOLSERVER" in the email message. You can leave the Subject: 
field of your email blank.

Reply via email to