Is there anyone who has an example of SSL Multithreading in Linux
platform.
I saw the example shipped with OpenSSL. But it seem to be bit unclear
for me. If anyone have an example on Multithreading please send me.
Ashada
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org
Hi,
I yanked these from the examples and put them in their own file. Call
SSL_Thread_setup before you spawn, and SSL_thread_cleanup when the
program terminates.
--
Jim McLaughlin
Software Engineer
Stonewater Software
Phone: 847-864-1060 x107
Fax : 847-864-1238
email: j...@stonewatersoftware.com
--------------F3811CD3D961C2584B6E310E
Content-Type: text/plain; charset=us-ascii;
name="SSL_Thread_Init.h"
Content-Disposition: inline;
filename="SSL_Thread_Init.h"
Content-Transfer-Encoding: 7bit
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
//#include <typedefs.h>
#include <openssl/e_os.h>
#include <pthread.h>
#include <openssl/lhash.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
static pthread_mutex_t *lock_cs;
static long *lock_count;
#ifdef __cplusplus
extern "C" {
#endif
void SSL_thread_setup(void);
void SSL_thread_cleanup(void);
void SSL_pthreads_locking_callback(int mode, int type, char *file, int line);
unsigned long SSL_pthreads_thread_id(void);
#ifdef __cplusplus
}
#endif
--------------F3811CD3D961C2584B6E310E
Content-Type: text/plain; charset=us-ascii;
name="SSL_Thread_Init.c"
Content-Disposition: inline;
filename="SSL_Thread_Init.c"
Content-Transfer-Encoding: 7bit
#include "SSL_Thread_Init.h"
void SSL_thread_setup(void) {
int i;
lock_cs=(pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
lock_count=(long *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
for (i=0; i<CRYPTO_num_locks(); i++) {
lock_count[i]=0;
pthread_mutex_init(&(lock_cs[i]),NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())SSL_pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())SSL_pthreads_locking_callback);
}
void SSL_thread_cleanup(void) {
int i;
CRYPTO_set_locking_callback(NULL);
fprintf(stderr,"cleanup\n");
for (i=0; i<CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
fprintf(stderr,"%8ld:%s\n",lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
fprintf(stderr,"done cleanup\n");
}
void SSL_pthreads_locking_callback(int mode, int type, char *file, int line) {
#ifdef undef
fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
CRYPTO_thread_id(),
(mode&CRYPTO_LOCK)?"l":"u",
(type&CRYPTO_READ)?"r":"w",file,line);
#endif
/*
if (CRYPTO_LOCK_SSL_CERT == type)
fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
CRYPTO_thread_id(),
mode,file,line);
*/
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
} else {
pthread_mutex_unlock(&(lock_cs[type]));
}
}
unsigned long SSL_pthreads_thread_id(void) {
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}
--------------F3811CD3D961C2584B6E310E--
[...]
unsigned long SSL_pthreads_thread_id(void) {
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}
[...]
The return type of pthread_self(), pthread_t, is not necessary a type
castable to unsigned long, which makes this piece somewhat non-portable.
Dima
Unfortunately, the function signature requires it:
void CRYPTO_set_id_callback(unsigned long (*id_function)(void));
--
Jim McLaughlin
Software Engineer
Stonewater Software
Phone: 847-864-1060 x107
Fax : 847-864-1238
email: j...@stonewatersoftware.com
> > unsigned long SSL_pthreads_thread_id(void) {
> > unsigned long ret;
> > ret=(unsigned long)pthread_self();
> > return(ret);
> > }
> > The return type of pthread_self(), pthread_t, is not necessary a type
> > castable to unsigned long, which makes this piece somewhat non-portable.
>
> Unfortunately, the function signature requires it:
> void CRYPTO_set_id_callback(unsigned long (*id_function)(void));
Yes, this is a pain. On those places where pthread_t is a scalar type,
it will work; on places where it's a struct, it will probably fail to
compile. You can work around that by doing
pthread_t me = pthread_self()
unsigned long ret;
memcpy(&ret, &me, sizeof ret)
return ret
But that's probably getting valid, but wrong and buggy :), code.
The attached code compiles, and should work portably. Something like it
should be used as a replacement for pthreads_thread_id that is currently
in crypto/threads/th-lock.c and for the code snippet above.
Hope this helps.
/r$
--
Zolera Systems, Your Key to Online Integrity
Securing Web services: XML, SOAP, Dig-sig, Encryption
http://www.zolera.com
--------------4A8CA4C0BAA069CA4BA0C1CE
Content-Type: text/plain; charset=us-ascii;
name="key.c"
Content-Disposition: inline;
filename="key.c"
Content-Transfer-Encoding: 7bit
/*
** Sample code, showing how to use POSIX threads's TSD to hold a
** small unique id value. Except for perhaps the header files, this
** should be highly portable code. (Famous last words.)
** This code is in the public domain, 27 Aug 2001.
** Rich Salz
** Zolera Systems, Your Key to Online Integrity
** Securing Web services: XML, SOAP, Dig-sig, Encryption
** http://www.zolera.com
*/
#include <pthread.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/* tid_once ensures the following are only initialized once. */
static pthread_once_t tid_once = PTHREAD_ONCE_INIT;
/* The key for storing our thread-specific data. */
static pthread_key_t tid_key;
/* The mutex that protects our global counter. */
static pthread_mutex_t tid_mutex;
/* Our local thread id. Also a hint that we're not initialized. */
static unsigned long tid = 0;
/*
** Initialization function. Create the TSD key, the mutex, and clear
** the counter.
*/
static void
init_openssl_tid(void)
{
int st;
st = pthread_key_create(&tid_key, NULL);
assert(st >= 0);
st = pthread_mutex_init(&tid_mutex, NULL);
assert(st >= 0);
tid = 0;
}
/*
** Return a unique ID for every thread. Imposes no overhead if never
** called.
*/
unsigned long SSL_pthreads_thread_id(void)
{
int st;
unsigned long* ulp;
void* vp;
/* Initialize if necessary. */
if (tid == 0)
pthread_once(&tid_once, init_openssl_tid);
/* Already know our ID? */
vp = pthread_getspecific(tid_key);
if (vp)
ulp = (unsigned long*)vp;
else {
/* No; lock and bump. */
ulp = (unsigned long*)malloc(sizeof *ulp);
st = pthread_mutex_lock(&tid_mutex);
assert(st >= 0);
*ulp = ++tid;
st = pthread_mutex_unlock(&tid_mutex);
assert(st >= 0);
pthread_setspecific(tid_key, ulp);
}
return *ulp;
}
--------------4A8CA4C0BAA069CA4BA0C1CE--