这星期在程序里的多线程使用openssl来进行ssl通信,看了一些openssl的文档,前两天领导提醒我注意使用锁,今晚发现openssl提供了非常简单的加锁方式:用户无需显式地进行加锁、解锁,只需提供2个回调函数:
1) void locking_function(int mode, int n, const char *file, int line);
2) unsigned long id_function(void);
对openssl设置这2个回调函数,在需要加锁、解锁时,openssl自动调用这2个函数。于是,过程大概如下:
- 自己实现回调函数1: locking_function
- 自己实现回调函数2: id_function
- 设置回调函数
上面的3个子过程大概又分别如下:
实现回调函数1: locking_function
// 这个数组需要自己申请空间,后续给到openssl使用 static pthread_mutex_t *ssl_lock = NULL; void locking_function(int mode, int type, char *file, int line) { // 根据第1个参数mode来判断是加锁还是解锁 // 第2个参数是数组下标 if (mode & CRYPTO_LOCK){ pthread_mutex_lock(&(ssl_lock[type])); }else{ pthread_mutex_unlock(&(ssl_lock[type])); } }
实现回调函数2: id_function
// 返回当前线程id unsigned long id_function(void) { unsigned long ret; ret=(unsigned long)pthread_self(); return(ret); }
设置回调函数
int create_ssl_lock(void) { int i; // 申请空间,锁的个数是:CRYPTO_num_locks(), ssl_lock = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); if (!ssl_lock) return -1; for (i =0 ; i < CRYPTO_num_locks(); i++){ pthread_mutex_init(&(ssl_lock[i]), NULL); } // 设置回调函数,获取当前线程id CRYPTO_set_id_callback((unsigned long (*)())id_function); // 设置回调函数,加锁和解锁 CRYPTO_set_locking_callback((void (*)())locking_function); return 0; }
释放资源
void ssl_lock_cleanup(void) { int i; if (!ssl_lock){ return; } CRYPTO_set_locking_callback(NULL); for (i = 0; i < CRYPTO_num_locks(); i++){ pthread_mutex_destroy(&(ssl_lock[i])); } OPENSSL_free(ssl_lock); ssl_lock = NULL; }
另外,在启动其他线程、初始化ssl之前调用
create_ssl_lock()
,在程序最后清理资源时调用ssl_lock_cleanup()
。最后总的流程大概为:
main start:
void init_ssl_env()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
if (create_ssl_lock()){
printf("create ssl lock buffer err:%m\n");
}
}
// 启动其他工作线程
// 线程里初始化ssl、使用ssl(不需显式地进行加锁、解锁)
void clean_ssl_env()
{
ssl_lock_cleanup();
ERR_free_strings();
}
main end
这里使用的是openssl的静态锁,固定申请CRYPTO_num_locks()
这么多个锁。 当然也可以使用动态锁,对性能还有提高。
但是,openssl的man页面上说,openssl内部当前不使用动态锁,未来也许会使用:
Also, dynamic locks are currently not used internally by OpenSSL, but may do so in the future.
参考自: Multithread Support
ps,推荐上面这本书《Cryptography for Secure Communications》,这里是pdf下载页面。
– EOF –