我有一个嵌入式应用程序,它使用 OpenSSL v0.9.7e 进行客户端 ssl 事务。我一直在使用与子线程共享的全局会话指针。它监控的每个 COM 端口都有一个线程。它在大多数情况下都有效。但是,每隔一段时间(每 500 次左右的事务),它就会在 SSL_connect() 内部崩溃。我做了一些探索,它似乎正在自行删除会话。因此,我怀疑其中一个线程在执行此操作时处于事务的中间。如果引用计数> 0,我会认为它不会删除它。
有谁知道是否可以通过全局共享会话来做到这一点?我是否应该每个线程(COM 端口)使用一个会话。这是代码。为简洁起见,我省略了所有错误检查。
int send_ssl_post(){
BIO *bio;
SSL *ssl;
int ret = -1;
int sockfd;
int sslRet;
ssl = NULL;
g_ctx = setup_client_ctx( );
ssl = SSL_new( g_ctx );
SSL_set_session( ssl, g_session );
sockfd = tcpConnect( url, true );
bio = BIO_new_socket( sockfd, BIO_NOCLOSE );
SSL_set_bio( ssl, bio, bio ); // SSL_set_bio cannot fail
sslRet = SSL_connect( ssl );
// free the session. We may change sessions below
if ( g_session != NULL ) {
SSL_SESSION_free( g_session );
}
// SSL write
ret = SSL_write( ssl, data, strlen( data ) );
ret = SSL_read( ssl, resp, respSize ); // time-out logic should be in
g_session = SSL_get1_session( ssl );
if ( ssl != NULL ) {
SSL_shutdown( ssl );
SSL_free( ssl );
}
if ( sockfd > 0 ){
close( sockfd );
}
ERR_remove_state( 0 ); // free the memory that did not freed (buggy in this SSL version)
return 0;
}
我也有两个thead锁定回调函数:
static void locking_function( int mode, int n, const char * file, int line ) {
if ( mode & CRYPTO_LOCK ){
//logger( DEBUG, "CRYPTO Lock file: %s, line: %d, n: %d", file, line, n );
pthread_mutex_lock( &ssl_mutex_array[n] );
} else {
//logger( DEBUG, "CRYPTO Unlock file: %s, line: %d, n: %d", file, line, n );
pthread_mutex_unlock( &ssl_mutex_array[n] );
}
}
static unsigned long id_function( void ) {
//logger( DEBUG, "CRYPTO Id function");
return ((unsigned long) pthread_self());
}
int setupSSLThreadLock( void ) {
int i;
//logger( DEBUG, "setupSSLThreadLock with %d number of locks", CRYPTO_num_locks() );
ssl_mutex_array = OPENSSL_malloc( CRYPTO_num_locks( ) * sizeof (pthread_mutex_t) );
if ( !ssl_mutex_array ){
return 0;
}
for ( i = 0; i < CRYPTO_num_locks( ); i++ ){
pthread_mutex_init( &ssl_mutex_array[i], NULL );
}
CRYPTO_set_id_callback( id_function );
CRYPTO_set_locking_callback( locking_function );
return 1;
}
int cleanupSSLThreadLock( void ) {
int i;
if ( ssl_mutex_array == NULL ){
return 0;
}
CRYPTO_set_id_callback( NULL );
CRYPTO_set_locking_callback( NULL );
for ( i = 0; i < CRYPTO_num_locks( ); i++ ){
pthread_mutex_destroy( &ssl_mutex_array[i] );
}
OPENSSL_free( ssl_mutex_array );
ssl_mutex_array = NULL;
return 1;
}
任何帮助将不胜感激。