Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 #include <stdlib.h>
00034 #include <openssl/crypto.h>
00035 #include "../../dprint.h"
00036 #include "../../locking.h"
00037
00038 static int n_static_locks=0;
00039 static gen_lock_set_t* static_locks=0;
00040
00041
00042
00043 struct CRYPTO_dynlock_value{
00044 gen_lock_t lock;
00045 };
00046
00047
00048 static struct CRYPTO_dynlock_value* dyn_create_f(const char* file, int line)
00049 {
00050 struct CRYPTO_dynlock_value* l;
00051
00052 l=shm_malloc(sizeof(struct CRYPTO_dynlock_value));
00053 if (l==0){
00054 LOG(L_CRIT, "ERROR: tls: dyn_create_f locking callback out of shm."
00055 " memory (called from %s:%d)\n", file, line);
00056 goto error;
00057 }
00058 if (lock_init(&l->lock)==0){
00059 LOG(L_CRIT, "ERROR: tls: dyn_create_f locking callback: lock "
00060 "initialization failed (called from %s:%d)\n", file, line);
00061 shm_free(l);
00062 goto error;
00063 }
00064 return l;
00065 error:
00066 return 0;
00067 }
00068
00069
00070
00071 static void dyn_lock_f(int mode, struct CRYPTO_dynlock_value* l,
00072 const char* file, int line)
00073 {
00074 if (l==0){
00075 LOG(L_CRIT, "BUG: tls: dyn_lock_f locking callback: null lock"
00076 " (called from %s:%d)\n", file, line);
00077
00078 return;
00079 }
00080 if (mode & CRYPTO_LOCK){
00081 lock_get(&l->lock);
00082 }else{
00083 lock_release(&l->lock);
00084 }
00085 }
00086
00087
00088
00089 static void dyn_destroy_f(struct CRYPTO_dynlock_value *l,
00090 const char* file, int line)
00091 {
00092 if (l==0){
00093 LOG(L_CRIT, "BUG: tls: dyn_destroy_f locking callback: null lock"
00094 " (called from %s:%d)\n", file, line);
00095 return;
00096 }
00097 lock_destroy(&l->lock);
00098 shm_free(l);
00099 }
00100
00101
00102
00103
00104 static void locking_f(int mode, int n, const char* file, int line)
00105 {
00106 if (n<0 || n>=n_static_locks){
00107 LOG(L_CRIT, "BUG: tls: locking_f (callback): invalid lock number: "
00108 " %d (range 0 - %d), called from %s:%d\n",
00109 n, n_static_locks, file, line);
00110 abort();
00111 }
00112 if (mode & CRYPTO_LOCK){
00113 lock_set_get(static_locks, n);
00114 }else{
00115 lock_set_release(static_locks, n);
00116 }
00117
00118 }
00119
00120
00121
00122 void tls_destroy_locks()
00123 {
00124 if (static_locks){
00125 lock_set_destroy(static_locks);
00126 lock_set_dealloc(static_locks);
00127 static_locks=0;
00128 n_static_locks=0;
00129 }
00130 }
00131
00132
00133
00134
00135 int tls_init_locks()
00136 {
00137
00138 n_static_locks=CRYPTO_num_locks();
00139 if (n_static_locks<0){
00140 LOG(L_CRIT, "BUG: tls: tls_init_locking: bad CRYPTO_num_locks %d\n",
00141 n_static_locks);
00142 n_static_locks=0;
00143 }
00144 if (n_static_locks){
00145 static_locks=lock_set_alloc(n_static_locks);
00146 if (static_locks==0){
00147 LOG(L_CRIT, "ERROR: tls_init_locking: could not allocate lockset"
00148 " with %d locks\n", n_static_locks);
00149 goto error;
00150 }
00151 if (lock_set_init(static_locks)==0){
00152 LOG(L_CRIT, "ERROR: tls_init_locking: lock_set_init failed "
00153 "(%d locks)\n", n_static_locks);
00154 lock_set_dealloc(static_locks);
00155 static_locks=0;
00156 n_static_locks=0;
00157 goto error;
00158 }
00159 CRYPTO_set_locking_callback(locking_f);
00160 }
00161
00162 CRYPTO_set_dynlock_create_callback(dyn_create_f);
00163 CRYPTO_set_dynlock_lock_callback(dyn_lock_f);
00164 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_f);
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 return 0;
00177 error:
00178 tls_destroy_locks();
00179 return -1;
00180 }