1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-06 13:20:57 +03:00

Openssl implementation of threading + default imp

This commit is contained in:
Aris Adamantiadis
2010-09-01 14:07:45 +02:00
parent 50d8d75d89
commit 8c55294ea9
8 changed files with 135 additions and 41 deletions

View File

@@ -62,6 +62,8 @@ else (WITH_GCRYPT)
endif (NOT OPENSSL_FOUND)
endif(WITH_GCRYPT)
#find out if we have threading available
include(FindThreads)
# config.h checks
include(ConfigureChecks.cmake)
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)

View File

@@ -58,6 +58,12 @@ check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
include(FindThreads)
if(CMAKE_HAVE_PTHREAD_H)
set(HAVE_PTHREAD_H)
endif(CMAKE_HAVE_PTHREAD_H)
# FUNCTIONS
if (UNIX)
@@ -114,6 +120,10 @@ if (WITH_DEBUG_CALLTRACE)
set(DEBUG_CALLTRACE 1)
endif (WITH_DEBUG_CALLTRACE)
if (CMAKE_HAVE_PTHREAD_CREATE)
set(HAVE_PTHREAD)
endif (CMAKE_HAVE_PTHREAD_CREATE)
# ENDIAN
if (NOT WIN32)
test_big_endian(WORDS_BIGENDIAN)

View File

@@ -35,6 +35,10 @@
/* Define to 1 if you have the <openssl/des.h> header file. */
#cmakedefine HAVE_OPENSSL_DES_H 1
/* Define to 1 if you have the <pthread.h> header file. */
#cmakedefine HAVE_PTHREAD_H 1
/*************************** FUNCTIONS ***************************/
/* Define to 1 if you have the `vsnprintf' function. */
@@ -78,6 +82,10 @@
/* Define to 1 if you have the `z' library (-lz). */
#cmakedefine HAVE_LIBZ 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
#cmakedefine HAVE_PTHREAD 1
/**************************** OPTIONS ****************************/
/* Define to 1 if you want to enable ZLIB */

View File

@@ -248,6 +248,21 @@ typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
*/
LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
/** @} */
typedef int (*ssh_thread_callback) (void **lock);
typedef unsigned long (*ssh_thread_id_callback) (void);
struct ssh_threads_callbacks_struct {
ssh_thread_callback mutex_init;
ssh_thread_callback mutex_destroy;
ssh_thread_callback mutex_lock;
ssh_thread_callback mutex_unlock;
ssh_thread_id_callback thread_id;
};
LIBSSH_API int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct
*cb);
#ifdef __cplusplus
}
#endif

View File

@@ -22,17 +22,10 @@
#ifndef THREADS_H_
#define THREADS_H_
typedef int (*ssh_thread_callback) (void **lock);
struct ssh_threads_callbacks_struct {
ssh_thread_callback mutex_init;
ssh_thread_callback mutex_destroy;
ssh_thread_callback mutex_lock;
ssh_thread_callback mutex_unlock;
};
#include <libssh/callbacks.h>
int ssh_threads_init(void);
int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct
*cb);
int ssh_init_set_threads_pthreads(void);
void ssh_threads_finalize(void);
#endif /* THREADS_H_ */

View File

@@ -55,6 +55,7 @@
#include "libssh/session.h"
#include "libssh/keys.h"
#include "libssh/dh.h"
#include "libssh/threads.h"
/* todo: remove it */
#include "libssh/string.h"
@@ -155,6 +156,7 @@ void ssh_crypto_finalize(void) {
bignum_free(p);
p = NULL;
ssh_crypto_initialized=0;
ssh_threads_finalize();
}
}

View File

@@ -30,10 +30,13 @@
#include "libssh/priv.h"
#include "libssh/threads.h"
#ifndef HAVE_PTHREAD
#warning "You do not have any threading library installed. If the linked"
#warning "application doesn't provide the threading callbacks, you're screwed"
#endif
#ifdef HAVE_LIBGCRYPT
#define HAVE_PTHREADS
#ifdef HAVE_PTHREADS
//#define HAVE_PTHREAD
#ifdef HAVE_PTHREAD
#include <errno.h>
#include <pthread.h>
@@ -66,31 +69,83 @@ static int ssh_pthread_mutex_unlock (void **lock){
return pthread_mutex_unlock (*lock);
}
static unsigned long ssh_pthread_thread_id (void){
return (unsigned long) pthread_self();
}
static struct ssh_threads_callbacks_struct ssh_gcrypt_user_callbacks=
static struct ssh_threads_callbacks_struct ssh_pthread_user_callbacks=
{
.mutex_init=ssh_pthread_mutex_init,
.mutex_destroy=ssh_pthread_mutex_destroy,
.mutex_lock=ssh_pthread_mutex_lock,
.mutex_unlock=ssh_pthread_mutex_unlock
.mutex_unlock=ssh_pthread_mutex_unlock,
.thread_id=ssh_pthread_thread_id
};
#endif
static struct gcry_thread_cbs gcrypt_threads_callbacks;
#endif
static struct ssh_threads_callbacks_struct *user_callbacks;
#ifdef HAVE_LIBGCRYPT
static void copy_callback(struct ssh_threads_callbacks_struct *cb){
/* Libgcrypt specific way of handling thread callbacks */
static struct gcry_thread_cbs gcrypt_threads_callbacks;
static int libgcrypt_thread_init(void){
if(user_callbacks == NULL)
return SSH_ERROR;
gcrypt_threads_callbacks.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_USER;
gcrypt_threads_callbacks.mutex_init=cb->mutex_init;
gcrypt_threads_callbacks.mutex_destroy=cb->mutex_destroy;
gcrypt_threads_callbacks.mutex_lock=cb->mutex_lock;
gcrypt_threads_callbacks.mutex_unlock=cb->mutex_unlock;
gcrypt_threads_callbacks.mutex_init=user_callbacks->mutex_init;
gcrypt_threads_callbacks.mutex_destroy=user_callbacks->mutex_destroy;
gcrypt_threads_callbacks.mutex_lock=user_callbacks->mutex_lock;
gcrypt_threads_callbacks.mutex_unlock=user_callbacks->mutex_unlock;
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks);
return SSH_OK;
}
#else
/* Libcrypto specific stuff */
void **libcrypto_mutexes;
static void libcrypto_lock_callback(int mode, int i, const char *file, int line){
(void)file;
(void)line;
if(mode & CRYPTO_LOCK){
user_callbacks->mutex_lock(&libcrypto_mutexes[i]);
} else {
user_callbacks->mutex_unlock(&libcrypto_mutexes[i]);
}
}
static int libcrypto_thread_init(){
int n=CRYPTO_num_locks();
int i;
libcrypto_mutexes=malloc(sizeof(void *) * n);
if (libcrypto_mutexes == NULL)
return SSH_ERROR;
for (i=0;i<n;++i){
user_callbacks->mutex_init(&libcrypto_mutexes[i]);
}
CRYPTO_set_id_callback(user_callbacks->thread_id);
CRYPTO_set_locking_callback(libcrypto_lock_callback);
return SSH_OK;
}
static void libcrypto_thread_finalize(){
int n=CRYPTO_num_locks();
int i;
if (libcrypto_mutexes==NULL)
return;
for (i=0;i<n;++i){
user_callbacks->mutex_destroy(&libcrypto_mutexes[i]);
}
SAFE_FREE(libcrypto_mutexes);
}
#endif
/** @internal
@@ -98,34 +153,38 @@ static void copy_callback(struct ssh_threads_callbacks_struct *cb){
*/
int ssh_threads_init(void){
#ifdef HAVE_LIBGCRYPT
if(user_callbacks != NULL){
copy_callback(user_callbacks);
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks);
return SSH_OK;
}
#ifdef HAVE_PTHREADS
else {
copy_callback(&ssh_gcrypt_user_callbacks);
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks);
return SSH_OK;
}
/* first initialize the user_callbacks with our default handlers if not
* already the case
*/
if(user_callbacks == NULL){
#ifdef HAVE_PTHREAD
user_callbacks=&ssh_pthread_user_callbacks;
} else {
#endif
#else
return SSH_ERROR; // Can't do anything to initialize threading
}
/* Then initialize the crypto libraries threading callbacks */
#ifdef HAVE_LIBGCRYPT
return libgcrypt_thread_init();
#else /* Libcrypto */
return libcrypto_thread_init();
#endif
return SSH_ERROR;
}
void ssh_threads_finalize(void){
#ifdef HAVE_LIBGCRYPT
#else
libcrypto_thread_finalize();
#endif
}
int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct *cb){
user_callbacks=cb;
return SSH_OK;
}
int ssh_init_set_threads_pthreads(void){
return SSH_OK;
}
/**
* @}
*/

View File

@@ -3,7 +3,12 @@
#include <pthread.h>
#include "torture.h"
#ifdef HAVE_LIBGCRYPT
#define NUM_LOOPS 1000
#else
/* openssl is much faster */
#define NUM_LOOPS 20000
#endif
#define NUM_THREADS 100
static void setup(){