M.S*_*sti 13 openssl reference pthreads
OpenSSL文档声明它可以安全地用于多线程应用程序,前提是至少设置了两个回调函数,locking_function和threadid_func ....
我编写了使用OpenSSL API的程序.而且,我知道如何使用pthreads.但是,OpenSSL文档是以手册的形式编写的,我无法看到在多线程应用程序中使用OpenSSL时我必须要做的一步一步的指导.
是否有关于使用OpenSSL和pthreads的教程?(我在网上搜索,但没有出现满意的结果.)
PS:我在Debian Lenny和Ubuntu Lucid/Maverick工作.
PS2: OpenSSL包含一个示例,但它开始时太复杂了.
M.S*_*sti 11
"Linux网络编程权威指南 "一书的第10章包括使用OpenSSL进行线程安全编程的一节(第255-259页).本节详细介绍了OpenSSL和pthreads库的工作原理.特别的,它告诉如何设置无论是在静态分配(其中的线程数是已知的回调函数先验)和动态分配(如创建和销毁线程在运行).
另一个很好的来源是OpenSSL网络安全一书的第4.1节,标题为多线程支持.它分别在4.1.1和4.1.2小节中提供静态/动态分配机制.
最后,有一本书Unix-Netzwerkprogrammierung mit Threads,Sockets und SSL,这是迄今为止关于这个主题的最全面的一本.不幸的是,这本德国书的英文翻译不可用.
不知道有关教程,但这里有两个基于libcurl的示例可能会有所帮助:
http://curl.haxx.se/libcurl/c/opensslthreadlock.html
http://curl.haxx.se/libcurl/c/threaded-ssl.html
必须使用threads选项配置openssl ./config thread -D_REENTRANT
这是复制和粘贴的问题; openssl tar ball包含一个文件样本crypto/threads/mttest.c
复制相关平台的具体实现并调用thread_setup进行初始化,并调用thread_cleanup进行包装;
基于 Wodin 使用 cURL 引用的回答,我所做的只是复制这 4 个函数
#include <openssl/crypto.h> //In addition to other ssl headers
Run Code Online (Sandbox Code Playgroud)
...
/* we have this global to let the callback get easy access to it */
static pthread_mutex_t *lockarray;
static void lock_callback(int mode, int type, char *file, int line)
{
(void)file;
(void)line;
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lockarray[type]));
}
else {
pthread_mutex_unlock(&(lockarray[type]));
}
}
static unsigned long thread_id(void)
{
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}
static void init_locks(void)
{
int i;
lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
sizeof(pthread_mutex_t));
for (i=0; i<CRYPTO_num_locks(); i++) {
pthread_mutex_init(&(lockarray[i]),NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())thread_id);
CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))lock_callback);
}
static void kill_locks(void)
{
int i;
CRYPTO_set_locking_callback(NULL);
for (i=0; i<CRYPTO_num_locks(); i++)
pthread_mutex_destroy(&(lockarray[i]));
OPENSSL_free(lockarray);
}
Run Code Online (Sandbox Code Playgroud)
然后调用这两个函数如下
int main(int argc, char **argv)
{
//pthread initialization goes here
init_locks();
//pthread stuff here (create, join, etc)
kill_locks();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这摆脱了SSL_load_error_strings();glibc中所有带有段错误和双重自由条件的奇怪错误。