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:
@@ -62,6 +62,8 @@ else (WITH_GCRYPT)
|
|||||||
endif (NOT OPENSSL_FOUND)
|
endif (NOT OPENSSL_FOUND)
|
||||||
endif(WITH_GCRYPT)
|
endif(WITH_GCRYPT)
|
||||||
|
|
||||||
|
#find out if we have threading available
|
||||||
|
include(FindThreads)
|
||||||
# config.h checks
|
# config.h checks
|
||||||
include(ConfigureChecks.cmake)
|
include(ConfigureChecks.cmake)
|
||||||
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||||
|
|||||||
@@ -58,6 +58,12 @@ check_include_file(openssl/blowfish.h HAVE_OPENSSL_BLOWFISH_H)
|
|||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIRS})
|
||||||
check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
|
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
|
# FUNCTIONS
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
@@ -114,6 +120,10 @@ if (WITH_DEBUG_CALLTRACE)
|
|||||||
set(DEBUG_CALLTRACE 1)
|
set(DEBUG_CALLTRACE 1)
|
||||||
endif (WITH_DEBUG_CALLTRACE)
|
endif (WITH_DEBUG_CALLTRACE)
|
||||||
|
|
||||||
|
if (CMAKE_HAVE_PTHREAD_CREATE)
|
||||||
|
set(HAVE_PTHREAD)
|
||||||
|
endif (CMAKE_HAVE_PTHREAD_CREATE)
|
||||||
|
|
||||||
# ENDIAN
|
# ENDIAN
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
test_big_endian(WORDS_BIGENDIAN)
|
test_big_endian(WORDS_BIGENDIAN)
|
||||||
|
|||||||
@@ -35,6 +35,10 @@
|
|||||||
/* Define to 1 if you have the <openssl/des.h> header file. */
|
/* Define to 1 if you have the <openssl/des.h> header file. */
|
||||||
#cmakedefine HAVE_OPENSSL_DES_H 1
|
#cmakedefine HAVE_OPENSSL_DES_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pthread.h> header file. */
|
||||||
|
#cmakedefine HAVE_PTHREAD_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************** FUNCTIONS ***************************/
|
/*************************** FUNCTIONS ***************************/
|
||||||
|
|
||||||
/* Define to 1 if you have the `vsnprintf' function. */
|
/* Define to 1 if you have the `vsnprintf' function. */
|
||||||
@@ -78,6 +82,10 @@
|
|||||||
/* Define to 1 if you have the `z' library (-lz). */
|
/* Define to 1 if you have the `z' library (-lz). */
|
||||||
#cmakedefine HAVE_LIBZ 1
|
#cmakedefine HAVE_LIBZ 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
|
#cmakedefine HAVE_PTHREAD 1
|
||||||
|
|
||||||
|
|
||||||
/**************************** OPTIONS ****************************/
|
/**************************** OPTIONS ****************************/
|
||||||
|
|
||||||
/* Define to 1 if you want to enable ZLIB */
|
/* Define to 1 if you want to enable ZLIB */
|
||||||
|
|||||||
@@ -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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,17 +22,10 @@
|
|||||||
#ifndef THREADS_H_
|
#ifndef THREADS_H_
|
||||||
#define THREADS_H_
|
#define THREADS_H_
|
||||||
|
|
||||||
typedef int (*ssh_thread_callback) (void **lock);
|
#include <libssh/callbacks.h>
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
int ssh_threads_init(void);
|
int ssh_threads_init(void);
|
||||||
int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct
|
void ssh_threads_finalize(void);
|
||||||
*cb);
|
|
||||||
int ssh_init_set_threads_pthreads(void);
|
|
||||||
|
|
||||||
#endif /* THREADS_H_ */
|
#endif /* THREADS_H_ */
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/keys.h"
|
#include "libssh/keys.h"
|
||||||
#include "libssh/dh.h"
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/threads.h"
|
||||||
|
|
||||||
/* todo: remove it */
|
/* todo: remove it */
|
||||||
#include "libssh/string.h"
|
#include "libssh/string.h"
|
||||||
@@ -155,6 +156,7 @@ void ssh_crypto_finalize(void) {
|
|||||||
bignum_free(p);
|
bignum_free(p);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
ssh_crypto_initialized=0;
|
ssh_crypto_initialized=0;
|
||||||
|
ssh_threads_finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
121
libssh/threads.c
121
libssh/threads.c
@@ -30,10 +30,13 @@
|
|||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/threads.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_PTHREAD
|
||||||
#define HAVE_PTHREADS
|
#ifdef HAVE_PTHREAD
|
||||||
#ifdef HAVE_PTHREADS
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
@@ -66,31 +69,83 @@ static int ssh_pthread_mutex_unlock (void **lock){
|
|||||||
return pthread_mutex_unlock (*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_init=ssh_pthread_mutex_init,
|
||||||
.mutex_destroy=ssh_pthread_mutex_destroy,
|
.mutex_destroy=ssh_pthread_mutex_destroy,
|
||||||
.mutex_lock=ssh_pthread_mutex_lock,
|
.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
|
#endif
|
||||||
|
|
||||||
static struct gcry_thread_cbs gcrypt_threads_callbacks;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct ssh_threads_callbacks_struct *user_callbacks;
|
static struct ssh_threads_callbacks_struct *user_callbacks;
|
||||||
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#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.option= GCRY_THREAD_OPTION_VERSION << 8 || GCRY_THREAD_OPTION_USER;
|
||||||
gcrypt_threads_callbacks.mutex_init=cb->mutex_init;
|
gcrypt_threads_callbacks.mutex_init=user_callbacks->mutex_init;
|
||||||
gcrypt_threads_callbacks.mutex_destroy=cb->mutex_destroy;
|
gcrypt_threads_callbacks.mutex_destroy=user_callbacks->mutex_destroy;
|
||||||
gcrypt_threads_callbacks.mutex_lock=cb->mutex_lock;
|
gcrypt_threads_callbacks.mutex_lock=user_callbacks->mutex_lock;
|
||||||
gcrypt_threads_callbacks.mutex_unlock=cb->mutex_unlock;
|
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
|
#endif
|
||||||
|
|
||||||
/** @internal
|
/** @internal
|
||||||
@@ -98,34 +153,38 @@ static void copy_callback(struct ssh_threads_callbacks_struct *cb){
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int ssh_threads_init(void){
|
int ssh_threads_init(void){
|
||||||
#ifdef HAVE_LIBGCRYPT
|
/* first initialize the user_callbacks with our default handlers if not
|
||||||
if(user_callbacks != NULL){
|
* already the case
|
||||||
copy_callback(user_callbacks);
|
*/
|
||||||
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks);
|
if(user_callbacks == NULL){
|
||||||
return SSH_OK;
|
#ifdef HAVE_PTHREAD
|
||||||
}
|
user_callbacks=&ssh_pthread_user_callbacks;
|
||||||
#ifdef HAVE_PTHREADS
|
} else {
|
||||||
else {
|
|
||||||
copy_callback(&ssh_gcrypt_user_callbacks);
|
|
||||||
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcrypt_threads_callbacks);
|
|
||||||
return SSH_OK;
|
|
||||||
}
|
|
||||||
#endif
|
#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
|
#endif
|
||||||
return SSH_ERROR;
|
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){
|
int ssh_init_set_threads_callbacks(struct ssh_threads_callbacks_struct *cb){
|
||||||
user_callbacks=cb;
|
user_callbacks=cb;
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_init_set_threads_pthreads(void){
|
|
||||||
return SSH_OK;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "torture.h"
|
#include "torture.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
#define NUM_LOOPS 1000
|
#define NUM_LOOPS 1000
|
||||||
|
#else
|
||||||
|
/* openssl is much faster */
|
||||||
|
#define NUM_LOOPS 20000
|
||||||
|
#endif
|
||||||
#define NUM_THREADS 100
|
#define NUM_THREADS 100
|
||||||
|
|
||||||
static void setup(){
|
static void setup(){
|
||||||
|
|||||||
Reference in New Issue
Block a user