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
00059 #include "mod.h"
00060
00061 #include "../../db/db.h"
00062 #include "../../sr_module.h"
00063 #include "../../timer.h"
00064 #include "../../locking.h"
00065 #include "../tm/tm_load.h"
00066 #include "../cdp/cdp_load.h"
00067 #include "../dialog/dlg_mod.h"
00068
00069 #include "registration.h"
00070 #include "registrar.h"
00071 #include "registrar_storage.h"
00072 #include "registrar_notify.h"
00073 #include "sip.h"
00074 #include "cx.h"
00075 #include "scscf_load.h"
00076 #include "dlg_state.h"
00077 #include "s_persistency.h"
00078 #include "ims_pm_scscf.h"
00079 #include "privacy.h"
00080
00081 MODULE_VERSION
00082
00083 static int mod_init(void);
00084 static int mod_child_init(int rank);
00085 static void mod_destroy(void);
00086
00087
00088
00089 char* scscf_name="sip:scscf.open-ims.test:6060";
00091 char* scscf_forced_hss_peer="";
00093 char *scscf_user_data_dtd=0;
00094 char *scscf_user_data_xsd=0;
00095
00096 int auth_data_hash_size=1024;
00097 int auth_vector_timeout=60;
00098 int auth_data_timeout=60;
00099 int av_request_at_once=1;
00100 int av_request_at_sync=1;
00103 int server_assignment_store_data=0;
00105 int registrar_hash_size=1024;
00106 int registration_default_expires=3600;
00107 int registration_min_expires=10;
00108 int registration_max_expires=1000000;
00109 char *registration_qop="auth,auth-int";
00110 str registration_qop_str={0,0};
00112 char* registration_default_algorithm="AKAv1-MD5";
00113 unsigned char registration_default_algorithm_type=1;
00114 int registration_disable_early_ims=1;
00115 int registration_disable_nass_bundled=1;
00117 int subscription_default_expires=3600;
00118 int subscription_min_expires=10;
00119 int subscription_max_expires=1000000;
00122 int append_branches=1;
00124 int scscf_dialogs_hash_size=256;
00125 int scscf_dialogs_expiration_time=3600;
00126 int scscf_dialogs_enable_release=1;
00127 int scscf_min_se=90;
00128 int* scscf_dialog_count = 0;
00129 int scscf_max_dialog_count=20000;
00130 gen_lock_t* scscf_dialog_count_lock=0;
00132 int scscf_support_wildcardPSI =0;
00133
00134 persistency_mode_t scscf_persistency_mode=NO_PERSISTENCY;
00135 char* scscf_persistency_location="/opt/OpenIMSCore/persistency";
00136 int scscf_persistency_timer_authdata=60;
00137 int scscf_persistency_timer_dialogs=60;
00138 int scscf_persistency_timer_registrar=60;
00139 char* scscf_db_url="postgres://mario:mario@localhost/scscfdb";
00140 int* auth_snapshot_version=0;
00141 int* auth_step_version=0;
00142 int* dialogs_snapshot_version=0;
00143 int* dialogs_step_version=0;
00144 int* registrar_snapshot_version=0;
00145 int* registrar_step_version=0;
00147 gen_lock_t* db_lock;
00149 #ifdef WITH_IMS_PM
00150
00151 char* ims_pm_node_type="S-CSCF";
00152 char* ims_pm_logfile="/opt/OpenIMSCore/default_ims_pm.log";
00153 #endif
00154
00155
00156
00157 str scscf_name_str;
00158 str scscf_record_route_mo;
00159 str scscf_record_route_mt;
00160 str scscf_record_route_mo_uri;
00161 str scscf_record_route_mt_uri;
00162 str scscf_service_route;
00163 str scscf_service_route_uri;
00164 str scscf_registration_min_expires;
00165 str scscf_subscription_min_expires;
00166 str scscf_forced_hss_peer_str;
00168 int * callback_singleton;
00169 int * shutdown_singleton;
00216 static cmd_export_t scscf_cmds[]={
00217 {"load_scscf", (cmd_function)load_scscf, NO_SCRIPT, 0, 0},
00218 {"get_r_public", (cmd_function)get_r_public, NO_SCRIPT, 0, 0},
00219 {"get_r_public_expires", (cmd_function)get_r_public_expires, NO_SCRIPT, 0, 0},
00220 {"r_unlock", (cmd_function)r_unlock, NO_SCRIPT, 0, 0},
00221
00222 {"S_is_integrity_protected", S_is_integrity_protected, 1,0,REQUEST_ROUTE},
00223 {"S_challenge", S_challenge, 1,0,REQUEST_ROUTE},
00224 {"S_is_authorized", S_is_authorized, 1,0,REQUEST_ROUTE},
00225 {"S_add_path_service_routes", S_add_path_service_routes, 0,0,REQUEST_ROUTE},
00226 {"S_add_allow", S_add_allow, 1,0,REQUEST_ROUTE},
00227 {"S_add_service_route", S_add_service_route, 1,0,REQUEST_ROUTE},
00228 {"S_check_visited_network_id", S_check_visited_network_id, 1, fixup_regex_1 ,REQUEST_ROUTE},
00229 {"S_add_p_charging_function_addresses", S_add_p_charging_function_addresses, 0, 0, REQUEST_ROUTE},
00230
00231 {"S_assign_server", S_assign_server, 1,0,REQUEST_ROUTE},
00232 {"S_assign_server_unreg", S_assign_server_unreg, 2,0,REQUEST_ROUTE},
00233 {"S_update_contacts", S_update_contacts, 0,0,REQUEST_ROUTE},
00234 {"S_lookup", S_lookup, 0,0,REQUEST_ROUTE|FAILURE_ROUTE},
00235
00236 {"S_is_not_registered", S_is_not_registered, 0,0,REQUEST_ROUTE},
00237
00238 {"S_term_registered", S_term_registered, 0,0,REQUEST_ROUTE|FAILURE_ROUTE},
00239 {"S_term_not_registered", S_term_not_registered, 0,0,REQUEST_ROUTE},
00240 {"S_term_unregistered", S_term_unregistered, 0,0,REQUEST_ROUTE},
00241
00242 {"S_orig_registered", S_orig_registered, 0,0,REQUEST_ROUTE},
00243 {"S_orig_not_registered", S_orig_not_registered, 0,0,REQUEST_ROUTE},
00244 {"S_orig_unregistered", S_orig_unregistered, 0,0,REQUEST_ROUTE},
00245
00246 {"S_can_subscribe", S_can_subscribe, 0,0,REQUEST_ROUTE},
00247 {"S_subscribe", S_subscribe, 0,0,REQUEST_ROUTE},
00248
00249 {"S_trans_in_processing", S_trans_in_processing, 0,0,REQUEST_ROUTE},
00250
00251
00252 {"S_mobile_originating", S_mobile_originating, 0,0,REQUEST_ROUTE},
00253
00254 {"S_originating_barred", S_originating_barred, 0,0,REQUEST_ROUTE},
00255 {"S_terminating_barred", S_terminating_barred, 0,0,REQUEST_ROUTE},
00256
00257 {"S_is_in_dialog", S_is_in_dialog, 1,0,REQUEST_ROUTE},
00258 {"S_save_dialog", S_save_dialog, 1,0,REQUEST_ROUTE|FAILURE_ROUTE},
00259 {"S_update_dialog", S_update_dialog, 1,0,REQUEST_ROUTE|ONREPLY_ROUTE},
00260 {"S_record_route", S_record_route, 1,0,REQUEST_ROUTE},
00261 {"S_is_record_routed", S_is_record_routed, 1,0,REQUEST_ROUTE},
00262 {"S_add_p_asserted_identity", S_add_p_asserted_identity, 0,0,REQUEST_ROUTE|FAILURE_ROUTE},
00263
00264 {"S_check_session_expires", S_check_session_expires, 0, 0, REQUEST_ROUTE},
00265 {"S_422_session_expires", S_422_session_expires, 0, 0, REQUEST_ROUTE},
00266
00267 {"S_privacy_hook", S_privacy_hook, 0, 0, REQUEST_ROUTE},
00268 {"S_apply_privacy", S_apply_privacy, 0, 0, REQUEST_ROUTE},
00269
00270 {0, 0, 0, 0, 0}
00271 };
00272
00321 static param_export_t scscf_params[]={
00322 {"name", STR_PARAM, &scscf_name},
00323
00324 {"forced_hss_peer", STR_PARAM, &scscf_forced_hss_peer},
00325
00326 {"auth_data_hash_size", INT_PARAM, &auth_data_hash_size},
00327 {"auth_vector_timeout", INT_PARAM, &auth_vector_timeout},
00328 {"auth_data_timeout", INT_PARAM, &auth_data_timeout},
00329 {"av_request_at_once", INT_PARAM, &av_request_at_once},
00330 {"av_request_at_sync", INT_PARAM, &av_request_at_sync},
00331
00332 {"server_assignment_store_data", INT_PARAM, &server_assignment_store_data},
00333
00334 {"user_data_dtd", STR_PARAM, &scscf_user_data_dtd},
00335 {"user_data_xsd", STR_PARAM, &scscf_user_data_xsd},
00336
00337 {"registrar_hash_size", INT_PARAM, ®istrar_hash_size},
00338 {"registration_default_expires", INT_PARAM, ®istration_default_expires},
00339 {"registration_min_expires", INT_PARAM, ®istration_min_expires},
00340 {"registration_max_expires", INT_PARAM, ®istration_max_expires},
00341 {"registration_qop", STR_PARAM, ®istration_qop},
00342 {"registration_default_algorithm", STR_PARAM, ®istration_default_algorithm},
00343 {"registration_disable_early_ims", INT_PARAM, ®istration_disable_early_ims},
00344 {"registration_disable_nass_bundled",INT_PARAM, ®istration_disable_nass_bundled},
00345
00346 {"subscription_default_expires", INT_PARAM, &subscription_default_expires},
00347 {"subscription_min_expires", INT_PARAM, &subscription_min_expires},
00348 {"subscription_max_expires", INT_PARAM, &subscription_max_expires},
00349
00350 {"append_branches", INT_PARAM, &append_branches},
00351
00352 {"dialogs_hash_size", INT_PARAM, &scscf_dialogs_hash_size},
00353 {"dialogs_expiration_time", INT_PARAM, &scscf_dialogs_expiration_time},
00354 {"dialogs_enable_release", INT_PARAM, &scscf_dialogs_enable_release},
00355 {"max_dialog_count", INT_PARAM, &scscf_max_dialog_count},
00356 {"min_se", INT_PARAM, &scscf_min_se},
00357 {"support_wildcardPSI", INT_PARAM, &scscf_support_wildcardPSI},
00358 {"persistency_mode", INT_PARAM, &scscf_persistency_mode},
00359 {"persistency_location", STR_PARAM, &scscf_persistency_location},
00360 {"persistency_timer_authdata", INT_PARAM, &scscf_persistency_timer_authdata},
00361 {"persistency_timer_dialogs", INT_PARAM, &scscf_persistency_timer_dialogs},
00362 {"persistency_timer_registrar", INT_PARAM, &scscf_persistency_timer_registrar},
00363 {"scscf_db_url", STR_PARAM, &scscf_db_url},
00364
00365 #ifdef WITH_IMS_PM
00366 {"ims_pm_node_type", STR_PARAM, &ims_pm_node_type},
00367 {"ims_pm_logfile", STR_PARAM, &ims_pm_logfile},
00368 #endif
00369
00370 {0,0,0}
00371 };
00372
00374 struct module_exports exports = {
00375 "scscf",
00376 scscf_cmds,
00377 0,
00378 scscf_params,
00379
00380 mod_init,
00381 0,
00382 mod_destroy,
00383 0,
00384 mod_child_init
00385 };
00386
00387
00389 int (*sl_reply)(struct sip_msg* _msg, char* _str1, char* _str2);
00392 struct tm_binds tmb;
00393 struct cdp_binds cdpb;
00394 dlg_func_t dialogb;
00396 extern auth_hash_slot_t *auth_data;
00397 extern r_hash_slot *registrar;
00398 extern r_notification_list *notification_list;
00400 extern s_dialog_hash_slot *s_dialogs;
00403 db_con_t* scscf_db = NULL;
00404 db_func_t scscf_dbf;
00406 static str s_qop_s={", qop=\"",7};
00407 static str s_qop_e={"\"",1};
00408 static str s_service_route = {"Service-Route: <",16};
00409 static str s_orig = {"sip:orig@",9};
00410 static str s_sr_end = {";lr>\r\n",6};
00411 static str s_min_expires_s={"Min-Expires: ",13};
00412 static str s_min_expires_e={"\r\n",2};
00413
00414 static str s_record_route_s={"Record-Route: <",15};
00415 static str s_mo = {"sip:mo@",7};
00416 static str s_mt = {"sip:mt@",7};
00417 static str s_record_route_e={";lr>\r\n",6};
00421 static inline int build_record_service_route()
00422 {
00423 scscf_service_route.s = pkg_malloc(s_service_route.len+s_orig.len+scscf_name_str.len+s_sr_end.len);
00424 if (!scscf_service_route.s){
00425 LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00426 s_service_route.len+s_orig.len+scscf_name_str.len+s_sr_end.len);
00427 return 0;
00428 }
00429 scscf_registration_min_expires.s = pkg_malloc(s_min_expires_s.len+10+s_min_expires_e.len);
00430 if (!scscf_registration_min_expires.s){
00431 LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00432 s_min_expires_s.len+10+s_min_expires_e.len);
00433 return 0;
00434 }
00435 scscf_subscription_min_expires.s = pkg_malloc(s_min_expires_s.len+10+s_min_expires_e.len);
00436 if (!scscf_subscription_min_expires.s){
00437 LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00438 s_min_expires_s.len+10+s_min_expires_e.len);
00439 return 0;
00440 }
00441
00442 if (registration_qop && strlen(registration_qop)>0) {
00443 registration_qop_str.len = s_qop_s.len+strlen(registration_qop)+s_qop_e.len;
00444 registration_qop_str.s = pkg_malloc(registration_qop_str.len);
00445 if (!registration_qop_str.s){
00446 LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",registration_qop_str.len);
00447 registration_qop_str.len = 0;
00448 return 0;
00449 }
00450 registration_qop_str.len = 0;
00451 STR_APPEND(registration_qop_str,s_qop_s);
00452 memcpy(registration_qop_str.s+registration_qop_str.len,registration_qop,strlen(registration_qop));
00453 registration_qop_str.len += strlen(registration_qop);
00454 STR_APPEND(registration_qop_str,s_qop_e);
00455 }else{
00456 registration_qop_str.len=0;
00457 registration_qop_str.s=0;
00458 }
00459
00460 scscf_record_route_mo.s = pkg_malloc(s_record_route_s.len+s_mo.len+scscf_name_str.len+s_record_route_e.len);
00461 if (!scscf_record_route_mo.s){
00462 LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00463 s_record_route_s.len+s_mo.len+scscf_name_str.len+s_record_route_e.len);
00464 return 0;
00465 }
00466 scscf_record_route_mt.s = pkg_malloc(s_record_route_s.len+s_mt.len+scscf_name_str.len+s_record_route_e.len);
00467 if (!scscf_record_route_mt.s){
00468 LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00469 s_record_route_s.len+s_mt.len+scscf_name_str.len+s_record_route_e.len);
00470 return 0;
00471 }
00472
00473 STR_APPEND(scscf_service_route,s_service_route);
00474 if (scscf_name_str.len>4 && strncasecmp(scscf_name_str.s,"sip:",4)==0){
00475 STR_APPEND(scscf_service_route,s_orig);
00476 memcpy(scscf_service_route.s+scscf_service_route.len,scscf_name_str.s+4,
00477 scscf_name_str.len-4);
00478 scscf_service_route.len += scscf_name_str.len-4;
00479 } else {
00480 STR_APPEND(scscf_service_route,s_orig);
00481 STR_APPEND(scscf_service_route,scscf_name_str);
00482 }
00483 STR_APPEND(scscf_service_route,s_sr_end);
00484 scscf_service_route_uri.s = scscf_service_route.s + s_service_route.len;
00485 scscf_service_route_uri.len = scscf_service_route.len - s_service_route.len - s_sr_end.len;
00486
00487 sprintf(scscf_registration_min_expires.s,"%.*s%d%.*s",
00488 s_min_expires_s.len,s_min_expires_s.s,
00489 registration_min_expires,
00490 s_min_expires_e.len,s_min_expires_e.s);
00491 scscf_registration_min_expires.len = strlen(scscf_registration_min_expires.s);
00492
00493 sprintf(scscf_subscription_min_expires.s,"%.*s%d%.*s",
00494 s_min_expires_s.len,s_min_expires_s.s,
00495 subscription_min_expires,
00496 s_min_expires_e.len,s_min_expires_e.s);
00497 scscf_subscription_min_expires.len = strlen(scscf_subscription_min_expires.s);
00498
00499 scscf_record_route_mo.len=0;
00500 STR_APPEND(scscf_record_route_mo,s_record_route_s);
00501 if (scscf_name_str.len>4 && strncasecmp(scscf_name_str.s,"sip:",4)==0){
00502 STR_APPEND(scscf_record_route_mo,s_mo);
00503 memcpy(scscf_record_route_mo.s+scscf_record_route_mo.len,scscf_name_str.s+4,
00504 scscf_name_str.len-4);
00505 scscf_record_route_mo.len += scscf_name_str.len-4;
00506 } else {
00507 STR_APPEND(scscf_record_route_mo,s_mo);
00508 STR_APPEND(scscf_record_route_mo,scscf_name_str);
00509 }
00510 STR_APPEND(scscf_record_route_mo,s_record_route_e);
00511 scscf_record_route_mo_uri.s = scscf_record_route_mo.s + s_record_route_s.len;
00512 scscf_record_route_mo_uri.len = scscf_record_route_mo.len - s_record_route_s.len - s_record_route_e.len;
00513
00514 scscf_record_route_mt.len=0;
00515 STR_APPEND(scscf_record_route_mt,s_record_route_s);
00516 if (scscf_name_str.len>4 && strncasecmp(scscf_name_str.s,"sip:",4)==0){
00517 STR_APPEND(scscf_record_route_mt,s_mt);
00518 memcpy(scscf_record_route_mt.s+scscf_record_route_mt.len,scscf_name_str.s+4,
00519 scscf_name_str.len-4);
00520 scscf_record_route_mt.len += scscf_name_str.len-4;
00521 } else {
00522 STR_APPEND(scscf_record_route_mt,s_mt);
00523 STR_APPEND(scscf_record_route_mt,scscf_name_str);
00524 }
00525 STR_APPEND(scscf_record_route_mt,s_record_route_e);
00526 scscf_record_route_mt_uri.s = scscf_record_route_mt.s + s_record_route_s.len;
00527 scscf_record_route_mt_uri.len = scscf_record_route_mt.len - s_record_route_s.len - s_record_route_e.len;
00528
00529
00530 return 1;
00531 }
00532
00533 db_con_t* create_scscf_db_connection()
00534 {
00535 if (scscf_persistency_mode!=WITH_DATABASE_BULK && scscf_persistency_mode!=WITH_DATABASE_CACHE) return NULL;
00536 if (!scscf_dbf.init) return NULL;
00537
00538 return scscf_dbf.init(scscf_db_url);
00539 }
00540
00544 static int mod_init(void)
00545 {
00546 load_tm_f load_tm;
00547 load_cdp_f load_cdp;
00548 bind_dlg_mod_f load_dlg;
00549 str algo;
00550
00551 callback_singleton=shm_malloc(sizeof(int));
00552 *callback_singleton=0;
00553 shutdown_singleton=shm_malloc(sizeof(int));
00554 *shutdown_singleton=0;
00555
00556
00557 LOG(L_INFO,"INFO:"M_NAME":mod_init: Initialization of module\n");
00558
00559 scscf_name_str.s = scscf_name;
00560 scscf_name_str.len = strlen(scscf_name);
00561 if (!build_record_service_route()) goto error;
00562 scscf_forced_hss_peer_str.s = scscf_forced_hss_peer;
00563 scscf_forced_hss_peer_str.len = strlen(scscf_forced_hss_peer);
00564
00565 algo.s = registration_default_algorithm;
00566 algo.len = strlen(registration_default_algorithm);
00567 registration_default_algorithm_type = get_algorithm_type(algo);
00568
00569
00570 #ifdef WITH_IMS_PM
00571 ims_pm_init(scscf_name_str,ims_pm_node_type, ims_pm_logfile);
00572 ims_pm_init_scscf();
00573 #endif
00574
00575
00576 sl_reply = find_export("sl_send_reply", 2, 0);
00577 if (!sl_reply) {
00578 LOG(L_ERR, "ERR"M_NAME":mod_init: This module requires sl module\n");
00579 goto error;
00580 }
00581
00582
00583
00584
00585 if(scscf_persistency_mode==WITH_DATABASE_BULK || scscf_persistency_mode==WITH_DATABASE_CACHE){
00586 if (!scscf_db_url) {
00587 LOG(L_ERR, "ERR:"M_NAME":mod_init: no db_url specified but DB has to be used "
00588 "(scscf_persistency_mode=%d\n", scscf_persistency_mode);
00589 return -1;
00590 }
00591 if (bind_dbmod(scscf_db_url, &scscf_dbf) < 0) {
00592 LOG(L_ERR, "ERR"M_NAME":mod_init: Can't bind database module via url %s\n", scscf_db_url);
00593 return -1;
00594 }
00595
00596 if (!DB_CAPABILITY(scscf_dbf, DB_CAP_ALL)) {
00597 LOG(L_ERR, "ERR:"M_NAME":mod_init: Database module does not implement all functions needed by the module\n");
00598 return -1;
00599 }
00600
00601 scscf_db = create_scscf_db_connection();
00602 if (!scscf_db) {
00603 LOG(L_ERR, "ERR:"M_NAME": mod_init: Error while connecting database\n");
00604 return -1;
00605 }
00606
00607
00608 db_lock = (gen_lock_t*)lock_alloc();
00609 if(!db_lock){
00610 LOG(L_ERR, "ERR:"M_NAME": mod_init: No memory left\n");
00611 return -1;
00612 }
00613 lock_init(db_lock);
00614
00615
00616
00617 auth_snapshot_version=(int*)shm_malloc(sizeof(int));
00618 if(!auth_snapshot_version){
00619 LOG(L_ERR, "ERR:"M_NAME":mod_init: auth_snapshot_version, no memory left\n");
00620 return -1;
00621 }
00622 *auth_snapshot_version=0;
00623
00624 auth_step_version=(int*)shm_malloc(sizeof(int));
00625 if(!auth_step_version){
00626 LOG(L_ERR, "ERR:"M_NAME":mod_init: auth_step_version, no memory left\n");
00627 return -1;
00628 }
00629 *auth_step_version=0;
00630
00631 dialogs_snapshot_version=(int*)shm_malloc(sizeof(int));
00632 if(!dialogs_snapshot_version){
00633 LOG(L_ERR, "ERR:"M_NAME":mod_init: dialogs_snapshot_version, no memory left\n");
00634 return -1;
00635 }
00636 *dialogs_snapshot_version=0;
00637
00638 dialogs_step_version=(int*)shm_malloc(sizeof(int));
00639 if(!dialogs_step_version){
00640 LOG(L_ERR, "ERR:"M_NAME":mod_init: dialogs_step_version, no memory left\n");
00641 return -1;
00642 }
00643 *dialogs_step_version=0;
00644
00645 registrar_snapshot_version=(int*)shm_malloc(sizeof(int));
00646 if(!registrar_snapshot_version){
00647 LOG(L_ERR, "ERR:"M_NAME":mod_init: registrar_snapshot_version, no memory left\n");
00648 return -1;
00649 }
00650 *registrar_snapshot_version=0;
00651
00652 registrar_step_version=(int*)shm_malloc(sizeof(int));
00653 if(!registrar_step_version){
00654 LOG(L_ERR, "ERR:"M_NAME":mod_init: registrar_step_version, no memory left\n");
00655 return -1;
00656 }
00657 *registrar_step_version=0;
00658
00659 }
00660
00661
00662 if (!(load_tm = (load_tm_f)find_export("load_tm",NO_SCRIPT,0))) {
00663 LOG(L_ERR, "ERR"M_NAME":mod_init: Can not import load_tm. This module requires tm module\n");
00664 goto error;
00665 }
00666 if (load_tm(&tmb) == -1)
00667 goto error;
00668
00669 if (!(load_cdp = (load_cdp_f)find_export("load_cdp",NO_SCRIPT,0))) {
00670 LOG(L_ERR, "ERR"M_NAME":mod_init: Can not import load_cdp. This module requires cdp module\n");
00671 goto error;
00672 }
00673 if (load_cdp(&cdpb) == -1)
00674 goto error;
00675
00676
00677 load_dlg = (bind_dlg_mod_f)find_export("bind_dlg_mod", -1, 0);
00678 if (!load_dlg) {
00679 LOG(L_ERR, "ERR"M_NAME":mod_init: Can not import bind_dlg_mod. This module requires dialog module\n");
00680 return -1;
00681 }
00682 if (load_dlg(&dialogb) != 0) {
00683 return -1;
00684 }
00685
00686
00687
00688 if (!auth_data_init(auth_data_hash_size)) goto error;
00689 if (scscf_persistency_mode!=NO_PERSISTENCY){
00690 load_snapshot_authdata();
00691 if (register_timer(persistency_timer_authdata,0,scscf_persistency_timer_authdata)<0) goto error;
00692 }
00693
00694
00695
00696 if (register_timer(reg_await_timer,auth_data,10)<0) goto error;
00697
00698
00699 if (!r_storage_init(registrar_hash_size)) goto error;
00700 if (scscf_persistency_mode!=NO_PERSISTENCY){
00701 load_snapshot_registrar();
00702 if (register_timer(persistency_timer_registrar,0,scscf_persistency_timer_registrar)<0) goto error;
00703 }
00704
00705
00706 if (register_timer(registrar_timer,registrar,10)<0) goto error;
00707
00708
00709 if (!r_notify_init()) goto error;
00710
00711
00712 if (register_timer(notification_timer,notification_list,5)<0) goto error;
00713
00714
00715 if (!s_dialogs_init(scscf_dialogs_hash_size)){
00716 LOG(L_ERR, "ERR"M_NAME":mod_init: Error initializing the Hash Table for stored dialogs\n");
00717 goto error;
00718 }
00719 scscf_dialog_count = shm_malloc(sizeof(int));
00720 *scscf_dialog_count = 0;
00721 scscf_dialog_count_lock = lock_alloc();
00722 scscf_dialog_count_lock = lock_init(scscf_dialog_count_lock);
00723
00724 if (scscf_persistency_mode!=NO_PERSISTENCY){
00725 load_snapshot_dialogs();
00726 if (register_timer(persistency_timer_dialogs,0,scscf_persistency_timer_dialogs)<0) goto error;
00727 }
00728
00729
00730 if (register_timer(dialog_timer,s_dialogs,60)<0) goto error;
00731
00732
00733
00734
00735
00736
00737
00738 return 0;
00739 error:
00740 return -1;
00741 }
00742
00743 extern gen_lock_t* process_lock;
00744
00745
00746 void close_scscf_db_connection(db_con_t* db)
00747 {
00748 if (db && scscf_dbf.close) scscf_dbf.close(db);
00749 }
00750
00754 static int mod_child_init(int rank)
00755 {
00756 LOG(L_INFO,"INFO:"M_NAME":mod_child_init: Initialization of module in child [%d] \n",
00757 rank);
00758
00759 if ( rank == PROC_MAIN || rank == PROC_TCP_MAIN )
00760 return 0;
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 lock_get(process_lock);
00779 if((*callback_singleton)==0){
00780 *callback_singleton=1;
00781 cdpb.AAAAddRequestHandler(CxRequestHandler,NULL);
00782 }
00783 lock_release(process_lock);
00784
00785 if (!parser_init(scscf_user_data_dtd,scscf_user_data_xsd)) return -1;
00786
00787 return 0;
00788 }
00789
00793 static void mod_destroy(void)
00794 {
00795 int do_destroy=0;
00796 LOG(L_INFO,"INFO:"M_NAME":mod_destroy: child exit\n");
00797 lock_get(process_lock);
00798 if((*shutdown_singleton)==0){
00799 *shutdown_singleton=1;
00800 do_destroy=1;
00801 }
00802 lock_release(process_lock);
00803 if (do_destroy){
00804 if (scscf_persistency_mode!=NO_PERSISTENCY){
00805
00806 make_snapshot_authdata();
00807 make_snapshot_dialogs();
00808 make_snapshot_registrar();
00809 }
00810
00811 auth_data_destroy();
00812 parser_destroy();
00813 r_notify_destroy();
00814 r_storage_destroy();
00815 s_dialogs_destroy();
00816 lock_get(scscf_dialog_count_lock);
00817 shm_free(scscf_dialog_count);
00818 lock_destroy(scscf_dialog_count_lock);
00819 pkg_free(scscf_service_route.s);
00820 }
00821
00822 if ( (scscf_persistency_mode==WITH_DATABASE_BULK || scscf_persistency_mode==WITH_DATABASE_CACHE) && scscf_db) {
00823 DBG("INFO:"M_NAME": ... closing db connection\n");
00824 close_scscf_db_connection(scscf_db);
00825 }
00826 scscf_db = NULL;
00827 #ifdef WITH_IMS_PM
00828 ims_pm_destroy();
00829 #endif
00830 }
00831
00832
00833
00834
00842 int S_trans_in_processing(struct sip_msg* msg, char* str1, char* str2)
00843 {
00844 unsigned int hash, label;
00845 if (tmb.t_get_trans_ident(msg,&hash,&label)<0)
00846 return CSCF_RETURN_FALSE;
00847 return CSCF_RETURN_TRUE;
00848 }