00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define FIFO_SET_PROB "rand_set_prob"
00047 #define FIFO_RESET_PROB "rand_reset_prob"
00048 #define FIFO_GET_PROB "rand_get_prob"
00049 #define FIFO_GET_HASH "get_config_hash"
00050 #define FIFO_CHECK_HASH "check_config_hash"
00051
00052
00053 #define MAX_FLAG_LEN 12
00054
00055 #define FIFO_SET_GFLAG "set_gflag"
00056 #define FIFO_IS_GFLAG "is_gflag"
00057 #define FIFO_RESET_GFLAG "reset_gflag"
00058 #define FIFO_GET_GFLAGS "get_gflags"
00059
00060 #include "../../sr_module.h"
00061 #include "../../error.h"
00062 #include "../../pvar.h"
00063 #include "../../ut.h"
00064 #include "../../mem/mem.h"
00065 #include "../../mem/shm_mem.h"
00066 #include "../../mi/mi.h"
00067 #include "../../mod_fix.h"
00068 #include "../../md5utils.h"
00069 #include "../../globals.h"
00070 #include "../../hash_func.h"
00071 #include "../../locking.h"
00072 #include <stdio.h>
00073 #include <stdlib.h>
00074
00075 MODULE_VERSION
00076
00077 static int set_prob(struct sip_msg*, char *, char *);
00078 static int reset_prob(struct sip_msg*, char *, char *);
00079 static int get_prob(struct sip_msg*, char *, char *);
00080 static int rand_event(struct sip_msg*, char *, char *);
00081 static int m_sleep(struct sip_msg*, char *, char *);
00082 static int m_usleep(struct sip_msg*, char *, char *);
00083 static int dbg_abort(struct sip_msg*, char*,char*);
00084 static int dbg_pkg_status(struct sip_msg*, char*,char*);
00085 static int dbg_shm_status(struct sip_msg*, char*,char*);
00086
00087 static int set_gflag(struct sip_msg*, char *, char *);
00088 static int reset_gflag(struct sip_msg*, char *, char *);
00089 static int is_gflag(struct sip_msg*, char *, char *);
00090
00091 static int cfg_lock(struct sip_msg*, char *, char *);
00092 static int cfg_unlock(struct sip_msg*, char *, char *);
00093
00094 static struct mi_root* mi_set_prob(struct mi_root* cmd, void* param );
00095 static struct mi_root* mi_reset_prob(struct mi_root* cmd, void* param );
00096 static struct mi_root* mi_get_prob(struct mi_root* cmd, void* param );
00097 static struct mi_root* mi_get_hash(struct mi_root* cmd, void* param );
00098 static struct mi_root* mi_check_hash(struct mi_root* cmd, void* param );
00099
00100 static struct mi_root* mi_set_gflag(struct mi_root* cmd, void* param );
00101 static struct mi_root* mi_reset_gflag(struct mi_root* cmd, void* param );
00102 static struct mi_root* mi_is_gflag(struct mi_root* cmd, void* param );
00103 static struct mi_root* mi_get_gflags(struct mi_root* cmd, void* param );
00104
00105
00106 static int pv_get_random_val(struct sip_msg *msg, pv_param_t *param,
00107 pv_value_t *res);
00108
00109
00110 static int fixup_prob( void** param, int param_no);
00111 static int fixup_gflags( void** param, int param_no);
00112
00113
00114 static int mod_init(void);
00115 static void mod_destroy(void);
00116
00117 static int initial_prob = 10;
00118 static int *probability;
00119
00120 static char config_hash[MD5_LEN];
00121 static char* hash_file = NULL;
00122
00123 static int initial_gflags=0;
00124 static unsigned int *gflags=0;
00125
00126 static gen_lock_set_t *_cfg_lock_set = NULL;
00127 static unsigned int _cfg_lock_size = 0;
00128
00129 static cmd_export_t cmds[]={
00130 {"rand_set_prob",
00131 (cmd_function)set_prob,
00132 1,
00133 fixup_prob, 0,
00134
00135 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00136 {"rand_reset_prob", (cmd_function)reset_prob, 0, 0, 0,
00137 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00138 {"rand_get_prob", (cmd_function)get_prob, 0, 0, 0,
00139 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00140 {"rand_event", (cmd_function)rand_event, 0, 0, 0,
00141 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00142 {"sleep", (cmd_function)m_sleep, 1, fixup_uint_null, 0,
00143 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00144 {"usleep", (cmd_function)m_usleep, 1, fixup_uint_null, 0,
00145 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00146 {"abort", (cmd_function)dbg_abort, 0, 0, 0,
00147 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00148 {"pkg_status", (cmd_function)dbg_pkg_status, 0, 0, 0,
00149 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00150 {"shm_status", (cmd_function)dbg_shm_status, 0, 0, 0,
00151 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00152 {"set_gflag", (cmd_function)set_gflag, 1, fixup_gflags, 0,
00153 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00154 {"reset_gflag", (cmd_function)reset_gflag, 1, fixup_gflags, 0,
00155 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00156 {"is_gflag", (cmd_function)is_gflag, 1, fixup_gflags, 0,
00157 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00158 {"lock", (cmd_function)cfg_lock, 1, fixup_spve_null, 0,
00159 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00160 {"unlock", (cmd_function)cfg_unlock, 1, fixup_spve_null, 0,
00161 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00162 {0, 0, 0, 0, 0, 0}
00163 };
00164
00165
00166 static param_export_t params[]={
00167 {"initial_probability", INT_PARAM, &initial_prob },
00168 {"initial_gflags", INT_PARAM, &initial_gflags },
00169 {"hash_file", STR_PARAM, &hash_file },
00170 {"lock_set_size", INT_PARAM, &_cfg_lock_size },
00171 {0,0,0}
00172 };
00173
00174
00175 static mi_export_t mi_cmds[] = {
00176 { FIFO_SET_PROB, mi_set_prob, 0, 0, 0 },
00177 { FIFO_RESET_PROB, mi_reset_prob, MI_NO_INPUT_FLAG, 0, 0 },
00178 { FIFO_GET_PROB, mi_get_prob, MI_NO_INPUT_FLAG, 0, 0 },
00179 { FIFO_GET_HASH, mi_get_hash, MI_NO_INPUT_FLAG, 0, 0 },
00180 { FIFO_CHECK_HASH, mi_check_hash, MI_NO_INPUT_FLAG, 0, 0 },
00181 { FIFO_SET_GFLAG, mi_set_gflag, 0, 0, 0 },
00182 { FIFO_RESET_GFLAG, mi_reset_gflag, 0, 0, 0 },
00183 { FIFO_IS_GFLAG, mi_is_gflag, 0, 0, 0 },
00184 { FIFO_GET_GFLAGS, mi_get_gflags, MI_NO_INPUT_FLAG, 0, 0 },
00185 { 0, 0, 0, 0, 0}
00186 };
00187
00188
00189 static pv_export_t mod_items[] = {
00190 { {"RANDOM", sizeof("RANDOM")-1}, PVT_OTHER, pv_get_random_val, 0,
00191 0, 0, 0, 0 },
00192 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00193 };
00194
00195
00196 struct module_exports exports = {
00197 "cfgutils",
00198 DEFAULT_DLFLAGS,
00199 cmds,
00200 params,
00201 0,
00202 mi_cmds,
00203 mod_items,
00204 0,
00205 mod_init,
00206 0,
00207 mod_destroy,
00208 0
00209 };
00210
00211
00212
00213 static int fixup_prob( void** param, int param_no)
00214 {
00215 unsigned int myint;
00216 str param_str;
00217
00218
00219 if (param_no!=1)
00220 return 0;
00221
00222 param_str.s=(char*) *param;
00223 param_str.len=strlen(param_str.s);
00224 str2int(¶m_str, &myint);
00225
00226 if (myint > 100) {
00227 LM_ERR("invalid probability <%d>\n", myint);
00228 return E_CFG;
00229 }
00230
00231 pkg_free(*param);
00232 *param=(void *)(long)myint;
00233 return 0;
00234 }
00235
00236
00237
00238
00239
00240 static int fixup_gflags( void** param, int param_no)
00241 {
00242 unsigned int myint;
00243 str param_str;
00244
00245
00246 if (param_no!=1)
00247 return 0;
00248
00249 param_str.s=(char*) *param;
00250 param_str.len=strlen(param_str.s);
00251
00252 if (str2int(¶m_str, &myint )<0) {
00253 LM_ERR("bad number <%s>\n", (char *)(*param));
00254 return E_CFG;
00255 }
00256 if ( myint >= 8*sizeof(*gflags) ) {
00257 LM_ERR("flag <%d> out of "
00258 "range [0..%lu]\n", myint, ((unsigned long)8*sizeof(*gflags))-1 );
00259 return E_CFG;
00260 }
00261
00262 myint = 1 << myint;
00263
00264 pkg_free(*param);
00265 *param=(void *)(long)myint;
00266 return 0;
00267 }
00268
00269
00270
00271
00272 static int set_gflag(struct sip_msg *bar, char *flag, char *foo)
00273 {
00274 (*gflags) |= (unsigned int)(long)flag;
00275 return 1;
00276 }
00277
00278
00279 static int reset_gflag(struct sip_msg *bar, char *flag, char *foo)
00280 {
00281 (*gflags) &= ~ ((unsigned int)(long)flag);
00282 return 1;
00283 }
00284
00285
00286 static int is_gflag(struct sip_msg *bar, char *flag, char *foo)
00287 {
00288 return ( (*gflags) & ((unsigned int)(long)flag)) ? 1 : -1;
00289 }
00290
00291
00292 static struct mi_root* mi_set_gflag(struct mi_root* cmd_tree, void* param )
00293 {
00294 unsigned int flag;
00295 struct mi_node* node;
00296
00297 node = cmd_tree->node.kids;
00298 if(node == NULL)
00299 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00300
00301 flag = 0;
00302 if( strno2int( &node->value, &flag) <0)
00303 goto error;
00304 if (!flag) {
00305 LM_ERR("incorrect flag\n");
00306 goto error;
00307 }
00308
00309 (*gflags) |= flag;
00310
00311 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00312 error:
00313 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00314 }
00315
00316
00317 static struct mi_root* mi_reset_gflag(struct mi_root* cmd_tree, void* param )
00318 {
00319 unsigned int flag;
00320 struct mi_node* node = NULL;
00321
00322 node = cmd_tree->node.kids;
00323 if(node == NULL)
00324 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00325
00326 flag = 0;
00327 if( strno2int( &node->value, &flag) <0)
00328 goto error;
00329 if (!flag) {
00330 LM_ERR("incorrect flag\n");
00331 goto error;
00332 }
00333
00334 (*gflags) &= ~ flag;
00335
00336 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00337 error:
00338 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00339 }
00340
00341
00342 static struct mi_root* mi_is_gflag(struct mi_root* cmd_tree, void* param )
00343 {
00344 unsigned int flag;
00345 struct mi_root* rpl_tree = NULL;
00346 struct mi_node* node = NULL;
00347
00348 node = cmd_tree->node.kids;
00349 if(node == NULL)
00350 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00351
00352 flag = 0;
00353 if( strno2int( &node->value, &flag) <0)
00354 goto error_param;
00355 if (!flag) {
00356 LM_ERR("incorrect flag\n");
00357 goto error_param;
00358 }
00359
00360 rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00361 if(rpl_tree ==0)
00362 return 0;
00363
00364 if( ((*gflags) & flag)== flag )
00365 node = add_mi_node_child( &rpl_tree->node, 0, 0, 0, "TRUE", 4);
00366 else
00367 node = add_mi_node_child( &rpl_tree->node, 0, 0, 0, "FALSE", 5);
00368
00369 if(node == NULL)
00370 {
00371 LM_ERR("failed to add node\n");
00372 free_mi_tree(rpl_tree);
00373 return 0;
00374 }
00375
00376 return rpl_tree;
00377 error_param:
00378 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00379 }
00380
00381
00382 static struct mi_root* mi_get_gflags(struct mi_root* cmd_tree, void* param )
00383 {
00384 struct mi_root* rpl_tree= NULL;
00385 struct mi_node* node= NULL;
00386
00387 rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN );
00388 if(rpl_tree == NULL)
00389 return 0;
00390
00391 node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "0x%X",(*gflags));
00392 if(node == NULL)
00393 goto error;
00394
00395 node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "%u",(*gflags));
00396 if(node == NULL)
00397 goto error;
00398
00399 return rpl_tree;
00400 error:
00401 free_mi_tree(rpl_tree);
00402 return 0;
00403 }
00404
00405
00406 static struct mi_root* mi_set_prob(struct mi_root* cmd, void* param )
00407 {
00408 unsigned int percent;
00409 struct mi_node* node;
00410
00411 node = cmd->node.kids;
00412 if(node == NULL)
00413 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00414
00415 if( str2int( &node->value, &percent) <0)
00416 goto error;
00417 if (percent > 100) {
00418 LM_ERR("incorrect probability <%u>\n", percent);
00419 goto error;
00420 }
00421 *probability = percent;
00422 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00423
00424 error:
00425 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00426 }
00427
00428 static struct mi_root* mi_reset_prob(struct mi_root* cmd, void* param )
00429 {
00430
00431 *probability = initial_prob;
00432 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN );
00433 }
00434
00435 static struct mi_root* mi_get_prob(struct mi_root* cmd, void* param )
00436 {
00437 struct mi_root* rpl_tree= NULL;
00438 struct mi_node* node= NULL;
00439 rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN );
00440 if(rpl_tree == NULL)
00441 return 0;
00442 node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "actual probability: %u percent\n",(*probability));
00443 if(node == NULL)
00444 goto error;
00445
00446 return rpl_tree;
00447
00448 error:
00449 free_mi_tree(rpl_tree);
00450 return 0;
00451 }
00452
00453 static struct mi_root* mi_get_hash(struct mi_root* cmd, void* param )
00454 {
00455 struct mi_root* rpl_tree= NULL;
00456 struct mi_node* node= NULL;
00457
00458 if (!hash_file) {
00459 LM_INFO("no hash_file given, disable hash functionality\n");
00460 rpl_tree = init_mi_tree(404, "Functionality disabled\n", 23);
00461 } else {
00462 rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN );
00463 if(rpl_tree == NULL)
00464 return 0;
00465 node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "%.*s\n", MD5_LEN, config_hash);
00466 if(node == NULL)
00467 goto error;
00468 }
00469 return rpl_tree;
00470
00471 error:
00472 free_mi_tree(rpl_tree);
00473 return 0;
00474 }
00475
00476 static struct mi_root* mi_check_hash(struct mi_root* cmd, void* param )
00477 {
00478 struct mi_root* rpl_tree= NULL;
00479 struct mi_node* node= NULL;
00480 char tmp[MD5_LEN];
00481 memset(tmp, 0, MD5_LEN);
00482
00483 if (!hash_file) {
00484 LM_INFO("no hash_file given, disable hash functionality\n");
00485 rpl_tree = init_mi_tree(404, "Functionality disabled\n", 23);
00486 } else {
00487 if (MD5File(tmp, hash_file) != 0) {
00488 LM_ERR("could not hash the config file");
00489 rpl_tree = init_mi_tree( 500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN );
00490 }
00491
00492 if (strncmp(config_hash, tmp, MD5_LEN) == 0) {
00493 rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN );
00494 if(rpl_tree == NULL)
00495 return 0;
00496 node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "The actual config file hash is identical to the stored one.\n");
00497 } else {
00498 rpl_tree = init_mi_tree( 400, "Error", 5 );
00499 if(rpl_tree == NULL)
00500 return 0;
00501 node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "The actual config file hash is not identical to the stored one.\n");
00502 }
00503 if(node == NULL)
00504 goto error;
00505 }
00506
00507 return rpl_tree;
00508
00509 error:
00510 free_mi_tree(rpl_tree);
00511 return 0;
00512 }
00513
00514 static int set_prob(struct sip_msg *bar, char *percent_par, char *foo)
00515 {
00516 *probability=(int)(long)percent_par;
00517 return 1;
00518 }
00519
00520 static int reset_prob(struct sip_msg *bar, char *percent_par, char *foo)
00521 {
00522 *probability=initial_prob;
00523 return 1;
00524 }
00525
00526 static int get_prob(struct sip_msg *bar, char *foo1, char *foo2)
00527 {
00528 return *probability;
00529 }
00530
00531 static int rand_event(struct sip_msg *bar, char *foo1, char *foo2)
00532 {
00533
00534
00535 if ((*probability) == 0) return -1;
00536 if ((*probability) == 100) return 1;
00537
00538 double tmp = ((double) rand() / RAND_MAX);
00539 LM_DBG("generated random %f\n", tmp);
00540 if (tmp < ((double) (*probability) / 100)) {
00541 LM_DBG("return true\n");
00542 return 1;
00543 }
00544 else {
00545 LM_DBG("return false\n");
00546 return -1;
00547 }
00548 }
00549
00550 static int pv_get_random_val(struct sip_msg *msg, pv_param_t *param,
00551 pv_value_t *res)
00552 {
00553 int n;
00554 int l = 0;
00555 char *ch;
00556
00557 if(msg==NULL || res==NULL)
00558 return -1;
00559
00560 n = rand();
00561 ch = int2str(n , &l);
00562 res->rs.s = ch;
00563 res->rs.len = l;
00564 res->ri = n;
00565 res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
00566
00567 return 0;
00568 }
00569
00570 static int m_sleep(struct sip_msg *msg, char *time, char *str2)
00571 {
00572 LM_DBG("sleep %lu seconds\n", (unsigned long)time);
00573 sleep((unsigned int)(unsigned long)time);
00574 return 1;
00575 }
00576
00577 static int m_usleep(struct sip_msg *msg, char *time, char *str2)
00578 {
00579 LM_DBG("sleep %lu microseconds\n", (unsigned long)time);
00580 sleep_us((unsigned int)(unsigned long)time);
00581 return 1;
00582 }
00583
00584 static int dbg_abort(struct sip_msg* msg, char* foo, char* bar)
00585 {
00586 LM_CRIT("abort called\n");
00587 abort();
00588 return 0;
00589 }
00590
00591 static int dbg_pkg_status(struct sip_msg* msg, char* foo, char* bar)
00592 {
00593 pkg_status();
00594 return 1;
00595 }
00596
00597 static int dbg_shm_status(struct sip_msg* msg, char* foo, char* bar)
00598 {
00599 shm_status();
00600 return 1;
00601 }
00602
00603 int cfg_lock_helper(struct sip_msg *msg, gparam_p key, int mode)
00604 {
00605 str s;
00606 unsigned int pos;
00607 if(fixup_get_svalue(msg, key, &s)!=0)
00608 {
00609 LM_ERR("cannot get first parameter\n");
00610 return -1;
00611 }
00612 pos = core_case_hash(&s, 0, _cfg_lock_size);
00613 LM_DBG("cfg_lock mode %d on %u\n", mode, pos);
00614 if(mode==0)
00615 lock_set_get(_cfg_lock_set, pos);
00616 else
00617 lock_set_release(_cfg_lock_set, pos);
00618 return 1;
00619 }
00620
00621 static int cfg_lock(struct sip_msg *msg, char *key, char *s2)
00622 {
00623 if(_cfg_lock_set==NULL || key==NULL)
00624 return -1;
00625 return cfg_lock_helper(msg, (gparam_p)key, 0);
00626 }
00627
00628 static int cfg_unlock(struct sip_msg *msg, char *key, char *s2)
00629 {
00630 if(_cfg_lock_set==NULL || key==NULL)
00631 return -1;
00632 return cfg_lock_helper(msg, (gparam_p)key, 1);
00633 }
00634
00635
00636 static int mod_init(void)
00637 {
00638 if (!hash_file) {
00639 LM_INFO("no hash_file given, disable hash functionality\n");
00640 } else {
00641 if (MD5File(config_hash, hash_file) != 0) {
00642 LM_ERR("could not hash the config file");
00643 return -1;
00644 }
00645 LM_DBG("config file hash is %.*s", MD5_LEN, config_hash);
00646 }
00647
00648 if (initial_prob > 100) {
00649 LM_ERR("invalid probability <%d>\n", initial_prob);
00650 return -1;
00651 }
00652 LM_DBG("initial probability %d percent\n", initial_prob);
00653
00654 probability=(int *) shm_malloc(sizeof(int));
00655
00656 if (!probability) {
00657 LM_ERR("no shmem available\n");
00658 return -1;
00659 }
00660 *probability = initial_prob;
00661
00662 gflags=(unsigned int *) shm_malloc(sizeof(unsigned int));
00663 if (!gflags) {
00664 LM_ERR(" no shmem available\n");
00665 return -1;
00666 }
00667 *gflags=initial_gflags;
00668 if(_cfg_lock_size>0 && _cfg_lock_size<=10)
00669 {
00670 _cfg_lock_size = 1<<_cfg_lock_size;
00671 _cfg_lock_set = lock_set_alloc(_cfg_lock_size);
00672 if(_cfg_lock_set==NULL || lock_set_init(_cfg_lock_set)==NULL)
00673 {
00674 LM_ERR("cannot initiate lock set\n");
00675 return -1;
00676 }
00677 }
00678 return 0;
00679 }
00680
00681
00682 static void mod_destroy(void)
00683 {
00684 if (probability)
00685 shm_free(probability);
00686 if (gflags)
00687 shm_free(gflags);
00688 if(_cfg_lock_set!=NULL)
00689 {
00690 lock_set_destroy(_cfg_lock_set);
00691 lock_set_dealloc(_cfg_lock_set);
00692 }
00693 }