mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
4.3 KiB
181 lines
4.3 KiB
/*
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2007 iptelorg GmbH
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
/*
|
|
* tls locking and atomic ops related init functions
|
|
*
|
|
* History:
|
|
* --------
|
|
* 2007-01-22 created by andrei
|
|
*/
|
|
/*!
|
|
* \file
|
|
* \brief SIP-router TLS support :: Locking
|
|
* \ingroup tls
|
|
* Module: \ref tls
|
|
*/
|
|
|
|
|
|
#include <stdlib.h> /* abort() */
|
|
#include <openssl/crypto.h>
|
|
#include "../../dprint.h"
|
|
#include "../../locking.h"
|
|
|
|
static int n_static_locks=0;
|
|
static gen_lock_set_t* static_locks=0;
|
|
|
|
/* "dynamic" locks */
|
|
|
|
struct CRYPTO_dynlock_value{
|
|
gen_lock_t lock;
|
|
};
|
|
|
|
|
|
static struct CRYPTO_dynlock_value* dyn_create_f(const char* file, int line)
|
|
{
|
|
struct CRYPTO_dynlock_value* l;
|
|
|
|
l=shm_malloc(sizeof(struct CRYPTO_dynlock_value));
|
|
if (l==0){
|
|
LOG(L_CRIT, "ERROR: tls: dyn_create_f locking callback out of shm."
|
|
" memory (called from %s:%d)\n", file, line);
|
|
goto error;
|
|
}
|
|
if (lock_init(&l->lock)==0){
|
|
LOG(L_CRIT, "ERROR: tls: dyn_create_f locking callback: lock "
|
|
"initialization failed (called from %s:%d)\n", file, line);
|
|
shm_free(l);
|
|
goto error;
|
|
}
|
|
return l;
|
|
error:
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static void dyn_lock_f(int mode, struct CRYPTO_dynlock_value* l,
|
|
const char* file, int line)
|
|
{
|
|
if (l==0){
|
|
LOG(L_CRIT, "BUG: tls: dyn_lock_f locking callback: null lock"
|
|
" (called from %s:%d)\n", file, line);
|
|
/* try to continue */
|
|
return;
|
|
}
|
|
if (mode & CRYPTO_LOCK){
|
|
lock_get(&l->lock);
|
|
}else{
|
|
lock_release(&l->lock);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void dyn_destroy_f(struct CRYPTO_dynlock_value *l,
|
|
const char* file, int line)
|
|
{
|
|
if (l==0){
|
|
LOG(L_CRIT, "BUG: tls: dyn_destroy_f locking callback: null lock"
|
|
" (called from %s:%d)\n", file, line);
|
|
return;
|
|
}
|
|
lock_destroy(&l->lock);
|
|
shm_free(l);
|
|
}
|
|
|
|
|
|
|
|
/* normal locking callback */
|
|
static void locking_f(int mode, int n, const char* file, int line)
|
|
{
|
|
if (n<0 || n>=n_static_locks){
|
|
LOG(L_CRIT, "BUG: tls: locking_f (callback): invalid lock number: "
|
|
" %d (range 0 - %d), called from %s:%d\n",
|
|
n, n_static_locks, file, line);
|
|
abort(); /* quick crash :-) */
|
|
}
|
|
if (mode & CRYPTO_LOCK){
|
|
lock_set_get(static_locks, n);
|
|
}else{
|
|
lock_set_release(static_locks, n);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tls_destroy_locks()
|
|
{
|
|
if (static_locks){
|
|
lock_set_destroy(static_locks);
|
|
lock_set_dealloc(static_locks);
|
|
static_locks=0;
|
|
n_static_locks=0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* returns -1 on error, 0 on success */
|
|
int tls_init_locks()
|
|
{
|
|
/* init "static" tls locks */
|
|
n_static_locks=CRYPTO_num_locks();
|
|
if (n_static_locks<0){
|
|
LOG(L_CRIT, "BUG: tls: tls_init_locking: bad CRYPTO_num_locks %d\n",
|
|
n_static_locks);
|
|
n_static_locks=0;
|
|
}
|
|
if (n_static_locks){
|
|
static_locks=lock_set_alloc(n_static_locks);
|
|
if (static_locks==0){
|
|
LOG(L_CRIT, "ERROR: tls_init_locking: could not allocate lockset"
|
|
" with %d locks\n", n_static_locks);
|
|
goto error;
|
|
}
|
|
if (lock_set_init(static_locks)==0){
|
|
LOG(L_CRIT, "ERROR: tls_init_locking: lock_set_init failed "
|
|
"(%d locks)\n", n_static_locks);
|
|
lock_set_dealloc(static_locks);
|
|
static_locks=0;
|
|
n_static_locks=0;
|
|
goto error;
|
|
}
|
|
CRYPTO_set_locking_callback(locking_f);
|
|
}
|
|
/* set "dynamic" locks callbacks */
|
|
CRYPTO_set_dynlock_create_callback(dyn_create_f);
|
|
CRYPTO_set_dynlock_lock_callback(dyn_lock_f);
|
|
CRYPTO_set_dynlock_destroy_callback(dyn_destroy_f);
|
|
|
|
/* thread id callback: not needed because ser doesn't use thread and
|
|
* openssl already uses getpid() (by default)
|
|
* CRYPTO_set_id_callback(id_f);
|
|
*/
|
|
/* atomic add -- since for now we don't have atomic_add
|
|
* (only atomic_inc), fallback to the default use-locks mode
|
|
* CRYPTO_set_add_lock_callback(atomic_add_f);
|
|
*/
|
|
|
|
|
|
return 0;
|
|
error:
|
|
tls_destroy_locks();
|
|
return -1;
|
|
}
|