mod.c

Go to the documentation of this file.
00001 /*
00002  * $Id: mod.c 477 2007-11-02 20:15:53Z vingarzan $
00003  *  
00004  * Copyright (C) 2004-2006 FhG Fokus
00005  *
00006  * This file is part of Open IMS Core - an open source IMS CSCFs & HSS
00007  * implementation
00008  *
00009  * Open IMS Core is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * For a license to use the Open IMS Core software under conditions
00015  * other than those described here, or to purchase support for this
00016  * software, please contact Fraunhofer FOKUS by e-mail at the following
00017  * addresses:
00018  *     info@open-ims.org
00019  *
00020  * Open IMS Core is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  * 
00025  * It has to be noted that this Open Source IMS Core System is not 
00026  * intended to become or act as a product in a commercial context! Its 
00027  * sole purpose is to provide an IMS core reference implementation for 
00028  * IMS technology testing and IMS application prototyping for research 
00029  * purposes, typically performed in IMS test-beds.
00030  * 
00031  * Users of the Open Source IMS Core System have to be aware that IMS
00032  * technology may be subject of patents and licence terms, as being 
00033  * specified within the various IMS-related IETF, ITU-T, ETSI, and 3GPP
00034  * standards. Thus all Open IMS Core users have to take notice of this 
00035  * fact and have to agree to check out carefully before installing, 
00036  * using and extending the Open Source IMS Core System, if related 
00037  * patents and licences may become applicable to the intended usage 
00038  * context.  
00039  *
00040  * You should have received a copy of the GNU General Public License
00041  * along with this program; if not, write to the Free Software
00042  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00043  * 
00044  */
00045  
00060 #include <ctype.h>
00061 #include <sys/types.h>
00062 #include <unistd.h>
00063 #include <sys/socket.h>
00064 #include <netinet/in.h>
00065 #include <arpa/inet.h>
00066 
00067 #include "mod.h"
00068 
00069 #include "../../db/db.h"
00070 #include "../../sr_module.h"
00071 #include "../../socket_info.h"
00072 #include "../../timer.h"
00073 #include "../../locking.h"
00074 #include "../tm/tm_load.h"
00075 #include "../dialog/dlg_mod.h"
00076 #include "../cdp/cdp_load.h"
00077 
00078 //#include "db.h"
00079 #include "registration.h"
00080 #include "registrar_storage.h"
00081 #include "registrar_subscribe.h"
00082 #include "registrar.h"
00083 #include "nat_helper.h"
00084 #include "security.h"
00085 #include "dlg_state.h"
00086 #include "sdp_util.h"
00087 #include "p_persistency.h"
00088 #include "release_call.h"
00089 #include "ims_pm_pcscf.h"
00090 
00091 
00092 MODULE_VERSION
00093 
00094 static int mod_init(void);
00095 static int mod_child_init(int rank);
00096 static void mod_destroy(void);
00097 
00098 
00099 /* parameters storage */
00100 char* pcscf_name="sip:pcscf.open-ims.test:4060";    
00103 /* P-Charging-Vector parameters */
00104 extern char* cscf_icid_value_prefix;            
00105 extern unsigned int* cscf_icid_value_count;     
00106 extern gen_lock_t* cscf_icid_value_count_lock;  
00107 extern char* cscf_icid_gen_addr;                
00108 extern char* cscf_orig_ioi;                     
00109 extern char* cscf_term_ioi;                     
00112 int   pcscf_use_ipsec=0;                    
00113 char* pcscf_ipsec_host="127.0.0.1";         
00114 int   pcscf_ipsec_port_c=4060;              
00115 int   pcscf_ipsec_port_s=4060;              
00117 int   pcscf_use_tls=0;                      
00118 int   pcscf_tls_port=4061;                  
00120 char* pcscf_ipsec_P_Inc_Req ="/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Inc_Req.sh";       
00121 char* pcscf_ipsec_P_Out_Rpl ="/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Out_Rpl.sh";       
00122 char* pcscf_ipsec_P_Out_Req ="/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Out_Req.sh";       
00123 char* pcscf_ipsec_P_Inc_Rpl ="/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Inc_Rpl.sh";       
00124 char* pcscf_ipsec_P_Drop    ="/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Drop.sh";      
00126 int registrar_hash_size=1024;               
00128 char *pcscf_reginfo_dtd="/opt/OpenIMSCore/ser_ims/pcscf/modules/pcscf/reginfo.dtd";
00129 int pcscf_subscribe_retries = 1;            
00131 int subscriptions_hash_size=1024;           
00133 int pcscf_dialogs_hash_size=1024;           
00134 int pcscf_dialogs_expiration_time=3600;     
00135 int pcscf_dialogs_enable_release=1;         
00136 int pcscf_min_se=90;                        
00137 int* pcscf_dialog_count = 0;                
00138 int pcscf_max_dialog_count=20000;           
00139 gen_lock_t* pcscf_dialog_count_lock=0;      
00142 int pcscf_nat_enable = 1;                   
00143 int pcscf_nat_ping = 1;                     
00144 int pcscf_nat_pingall = 0;                  
00145 int pcscf_nat_detection_type = 0;           
00147 struct socket_info* force_socket = 0;       
00149 struct rtpp_head rtpp_list;                 
00150 int rtpp_node_count = 0;                    
00151 char *force_socket_str = 0 ;                
00152 char *rtpproxy_sock = "unix:/var/run/rtpproxy.sock"; /* list of RTPProxy sockets                */
00153 int rtpproxy_enable = 0;                    
00154 int rtpproxy_disable_tout = 60 ;            
00155 int rtpproxy_retr = 5;                      
00156 int rtpproxy_tout = 1;                      
00158 /* e2 interface with CLF */
00159 char* forced_clf_peer="";       
00160 int pcscf_use_e2=0;                             
00163 /* fixed parameter storage */
00164 str pcscf_name_str;                         
00165 str pcscf_path_hdr_str;                     
00166 str pcscf_path_str;                         
00168 str forced_clf_peer_str;                    
00170 str pcscf_record_route_mo;                  
00171 str pcscf_record_route_mo_uri;              
00172 str pcscf_record_route_mt;                  
00173 str pcscf_record_route_mt_uri;              
00175 extern str cscf_icid_value_prefix_str;              
00176 extern str cscf_icid_gen_addr_str;                  
00177 extern str cscf_orig_ioi_str;                       
00178 extern str cscf_term_ioi_str;                       
00181 persistency_mode_t pcscf_persistency_mode=NO_PERSISTENCY;           
00182 char* pcscf_persistency_location="/opt/OpenIMSCore/persistency";    
00183 int pcscf_persistency_timer_dialogs=60;                             
00184 int pcscf_persistency_timer_registrar=60;                           
00185 int pcscf_persistency_timer_subscriptions=60;                       
00186 char* pcscf_db_url="postgres://mario:mario@localhost/pcscfdb";
00187 int* subs_snapshot_version; 
00188 int* subs_step_version; 
00189 int* dialogs_snapshot_version; 
00190 int* dialogs_step_version; 
00191 int* registrar_snapshot_version; 
00192 int* registrar_step_version; 
00194 gen_lock_t* db_lock; 
00196 int * shutdown_singleton;               
00198 #ifdef WITH_IMS_PM
00199 
00200     char* ims_pm_node_type="P-CSCF";
00201     char* ims_pm_logfile="/opt/OpenIMSCore/default_ims_pm.log";
00202 #endif /* WITH_IMS_PM */
00203 
00204 
00267 static cmd_export_t pcscf_cmds[]={
00268     {"P_add_path",                  P_add_path,                 0, 0, REQUEST_ROUTE},
00269     {"P_add_require",               P_add_require,              0, 0, REQUEST_ROUTE},
00270     {"P_add_p_charging_vector",     P_add_p_charging_vector,    0, 0, REQUEST_ROUTE},
00271     {"P_add_integrity_protected",   P_add_integrity_protected,  1, 0, REQUEST_ROUTE},
00272     {"P_add_p_visited_network_id",  P_add_p_visited_network_id, 1, 0, REQUEST_ROUTE},
00273     
00274     {"P_remove_ck_ik",              P_remove_ck_ik,             0, 0, ONREPLY_ROUTE},
00275     {"P_remove_security_client",    P_remove_security_client,   0, 0, REQUEST_ROUTE},   
00276     {"P_remove_security_verify",    P_remove_security_verify,   0, 0, REQUEST_ROUTE},   
00277     {"P_remove_security_headers",   P_remove_security_headers,  0, 0, REQUEST_ROUTE},   
00278     {"P_remove_header_tag",         P_remove_header_tag,        2, 0, REQUEST_ROUTE},
00279 
00280     {"P_verify_security",           P_verify_security,          0, 0, REQUEST_ROUTE},
00281     {"P_security_401",              P_security_401,             0, 0, ONREPLY_ROUTE},
00282     {"P_security_200",              P_security_200,             0, 0, ONREPLY_ROUTE},   
00283     {"P_is_integrity_protected",    P_is_integrity_protected,   0, 0, REQUEST_ROUTE},   
00284     {"P_security_relay",            P_security_relay,           0, 0, REQUEST_ROUTE|ONREPLY_ROUTE},
00285     
00286     {"P_save_location",             P_save_location,            0, 0, ONREPLY_ROUTE},   
00287     {"P_subscribe",                 P_subscribe,                0, 0, ONREPLY_ROUTE},   
00288     {"P_is_registered",             P_is_registered,            0, 0, REQUEST_ROUTE},
00289     {"P_assert_identity",           P_assert_identity,          0, 0, REQUEST_ROUTE},
00290 
00291     {"P_process_notification",      P_process_notification,     0, 0, REQUEST_ROUTE},
00292 
00293     {"P_mobile_terminating",        P_mobile_terminating,       0, 0, REQUEST_ROUTE},
00294     {"P_remove_route",              P_remove_route,             1, 0, REQUEST_ROUTE},
00295     
00296     {"P_NAT_relay",                 P_NAT_relay,                0, 0, REQUEST_ROUTE|ONREPLY_ROUTE},
00297     {"P_SDP_manipulate",            P_SDP_manipulate,           0, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
00298     
00299     {"P_follows_service_routes",    P_follows_service_routes,   0, 0, REQUEST_ROUTE},
00300     {"P_enforce_service_routes",    P_enforce_service_routes,   0, 0, REQUEST_ROUTE},
00301 
00302     {"P_is_in_dialog",              P_is_in_dialog,             1, 0, REQUEST_ROUTE},
00303     {"P_save_dialog",               P_save_dialog,              1, 0, REQUEST_ROUTE},
00304     {"P_update_dialog",             P_update_dialog,            1, 0, REQUEST_ROUTE|ONREPLY_ROUTE},
00305     {"P_drop_dialog",               P_drop_dialog,              1, 0, ONREPLY_ROUTE|FAILURE_ROUTE},
00306     {"P_follows_dialog_routes",     P_follows_dialog_routes,    1, 0, REQUEST_ROUTE},
00307     {"P_enforce_dialog_routes",     P_enforce_dialog_routes,    1, 0, REQUEST_ROUTE},
00308     {"P_record_route",              P_record_route,             1, 0, REQUEST_ROUTE},       
00309     {"P_check_session_expires",     P_check_session_expires,    0, 0, REQUEST_ROUTE},
00310     {"P_422_session_expires",       P_422_session_expires,      0, 0, REQUEST_ROUTE},
00311 
00312     {"P_assert_called_identity",    P_assert_called_identity,   0, 0, ONREPLY_ROUTE},
00313     
00314     {"P_trans_in_processing",       P_trans_in_processing,      0, 0, REQUEST_ROUTE},
00315 
00316     {"P_check_via_sent_by",         P_check_via_sent_by,        0, 0, REQUEST_ROUTE},
00317     {"P_add_via_received",          P_add_via_received,         0, 0, REQUEST_ROUTE},
00318     
00319     {"P_follows_via_list",          P_follows_via_list,         0, 0, ONREPLY_ROUTE|FAILURE_ROUTE},
00320     {"P_enforce_via_list",          P_enforce_via_list,         0, 0, ONREPLY_ROUTE|FAILURE_ROUTE},
00321     {"P_release_call_onreply",      P_release_call_onreply,     1, 0,  ONREPLY_ROUTE},
00322     
00323     {"P_access_network_info",   P_access_network_info,          1, 0, REQUEST_ROUTE},
00324     
00325     {0, 0, 0, 0, 0}
00326 }; 
00327 
00382 static param_export_t pcscf_params[]={ 
00383     {"name", STR_PARAM, &pcscf_name},
00384 
00385     {"registrar_hash_size",     INT_PARAM,      &registrar_hash_size},
00386     {"reginfo_dtd",             STR_PARAM,      &pcscf_reginfo_dtd},
00387     {"subscriptions_hash_size", INT_PARAM,      &subscriptions_hash_size},
00388 
00389     {"dialogs_hash_size",       INT_PARAM,      &pcscf_dialogs_hash_size},
00390     {"dialogs_expiration_time", INT_PARAM,      &pcscf_dialogs_expiration_time},
00391     {"dialogs_enable_release",  INT_PARAM,      &pcscf_dialogs_enable_release},
00392     {"max_dialog_count",        INT_PARAM,      &pcscf_max_dialog_count},
00393     {"min_se",                  INT_PARAM,      &pcscf_min_se},
00394     
00395     
00396     {"use_ipsec",               INT_PARAM,      &pcscf_use_ipsec},
00397     {"ipsec_host",              STR_PARAM,      &pcscf_ipsec_host}, 
00398     {"ipsec_port_c",            INT_PARAM,      &pcscf_ipsec_port_c},
00399     {"ipsec_port_s",            INT_PARAM,      &pcscf_ipsec_port_s},
00400     
00401     {"use_tls",                 INT_PARAM,      &pcscf_use_tls},
00402     {"tls_port",                INT_PARAM,      &pcscf_tls_port},
00403     
00404     {"ipsec_P_Inc_Req",         STR_PARAM,      &pcscf_ipsec_P_Inc_Req},
00405     {"ipsec_P_Out_Rpl",         STR_PARAM,      &pcscf_ipsec_P_Out_Rpl},
00406     {"ipsec_P_Out_Req",         STR_PARAM,      &pcscf_ipsec_P_Out_Req},
00407     {"ipsec_P_Inc_Rpl",         STR_PARAM,      &pcscf_ipsec_P_Inc_Rpl},
00408     {"ipsec_P_Drop",            STR_PARAM,      &pcscf_ipsec_P_Drop},
00409     
00410     {"NAT_enable",              INT_PARAM,      &pcscf_nat_enable},
00411     {"ping",                    INT_PARAM,      &pcscf_nat_ping},
00412     {"ping_all",                INT_PARAM,      &pcscf_nat_pingall},
00413     {"nat_detection_type",      INT_PARAM,      &pcscf_nat_detection_type},
00414     
00415     {"rtpproxy_enable",         PARAM_INT,      &rtpproxy_enable      },
00416     {"rtpproxy_socket",         PARAM_STRING,   &rtpproxy_sock},
00417     {"rtpproxy_disable_tout",   PARAM_INT,      &rtpproxy_disable_tout },
00418     {"rtpproxy_retr",           PARAM_INT,      &rtpproxy_retr         },
00419     {"rtpproxy_tout",           PARAM_INT,      &rtpproxy_tout         },
00420     
00421     {"subscribe_retries",       INT_PARAM,      &pcscf_subscribe_retries},
00422     
00423     {"icid_value_prefix",       STR_PARAM,      &cscf_icid_value_prefix},
00424     {"icid_gen_addr",           STR_PARAM,      &cscf_icid_gen_addr},
00425     {"orig_ioi",                STR_PARAM,      &cscf_orig_ioi},
00426     {"term_ioi",                STR_PARAM,      &cscf_term_ioi},
00427 
00428     {"persistency_mode",                INT_PARAM, &pcscf_persistency_mode},    
00429     {"persistency_location",            STR_PARAM, &pcscf_persistency_location},
00430     {"persistency_timer_dialogs",       INT_PARAM, &pcscf_persistency_timer_dialogs},
00431     {"persistency_timer_registrar",     INT_PARAM, &pcscf_persistency_timer_registrar},
00432     {"persistency_timer_subscriptions", INT_PARAM, &pcscf_persistency_timer_subscriptions},
00433     {"pcscf_db_url",                    STR_PARAM, &pcscf_db_url},
00434     
00435 #ifdef WITH_IMS_PM
00436     {"ims_pm_node_type",                STR_PARAM, &ims_pm_node_type},
00437     {"ims_pm_logfile",                  STR_PARAM, &ims_pm_logfile},
00438 #endif /* WITH_IMS_PM */    
00439     
00440     
00441     {"forced_clf_peer",                 STR_PARAM, &forced_clf_peer},
00442     {"use_e2",                          INT_PARAM, &pcscf_use_e2},
00443     {0,0,0} 
00444 };
00445 
00447 struct module_exports exports = {
00448     "pcscf", 
00449     pcscf_cmds,
00450     0,
00451     pcscf_params,
00452     
00453     mod_init,       /* module initialization function */
00454     0,              /* response function*/
00455     mod_destroy,    /* destroy function */
00456     0,              /* onbreak function */
00457     mod_child_init  /* per-child init function */
00458 };
00459 
00460 
00461 /* Global variables and imported functions */
00462 int (*sl_reply)(struct sip_msg* _msg, char* _str1, char* _str2); 
00465 struct tm_binds tmb;                    
00466 dlg_func_t dialogb;                     
00467 struct cdp_binds cdpb;                  
00469 extern r_hash_slot *registrar;          
00471 extern p_dialog_hash_slot *p_dialogs;   
00474 db_con_t* pcscf_db = NULL; 
00475 db_func_t pcscf_dbf;    
00477 static str path_str_s={"Path: <",7};
00478 static str path_str_1={"sip:term@",9};
00479 static str path_str_e={";lr>\r\n",6};
00480 
00481 static str s_record_route_s={"Record-Route: <",15};
00482 static str s_mo = {"sip:mo@",7};
00483 static str s_mt = {"sip:mt@",7};
00484 static str s_record_route_e={";lr>\r\n",6};
00485 
00489 int fix_parameters()
00490 {
00491     str x;  
00492         
00493     pcscf_name_str.s = pcscf_name;
00494     pcscf_name_str.len = strlen(pcscf_name);    
00495     
00496     x = pcscf_name_str;
00497     if (pcscf_name_str.len>=4 &&
00498         strncasecmp(pcscf_name_str.s,"sip:",4)==0) 
00499     {
00500         x.s += 4;
00501         x.len -= 4; 
00502     }
00503     pcscf_path_str.len = path_str_1.len+x.len;
00504     pcscf_path_str.s = pkg_malloc(pcscf_path_str.len);
00505     if (!pcscf_path_str.s){
00506         LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00507             pcscf_path_str.len);
00508         pcscf_path_str.len=0;
00509         return 0;
00510     }
00511     pcscf_path_str.len=0;
00512     STR_APPEND(pcscf_path_str,path_str_1);
00513     STR_APPEND(pcscf_path_str,x);
00514 
00515     pcscf_path_hdr_str.len = path_str_s.len + pcscf_path_str.len + path_str_e.len;
00516     pcscf_path_hdr_str.s = pkg_malloc(pcscf_path_hdr_str.len);
00517     if (!pcscf_path_hdr_str.s){
00518         LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00519             pcscf_path_hdr_str.len);
00520         pcscf_path_hdr_str.len=0;
00521         return 0;
00522     }
00523     pcscf_path_hdr_str.len=0;
00524     STR_APPEND(pcscf_path_hdr_str,path_str_s);  
00525     STR_APPEND(pcscf_path_hdr_str,pcscf_path_str);
00526     STR_APPEND(pcscf_path_hdr_str,path_str_e);
00527         
00528     cscf_icid_value_prefix_str.s = cscf_icid_value_prefix;
00529     cscf_icid_value_prefix_str.len = strlen(cscf_icid_value_prefix);
00530 
00531     cscf_icid_gen_addr_str.s = cscf_icid_gen_addr;
00532     cscf_icid_gen_addr_str.len = strlen(cscf_icid_gen_addr);
00533     
00534     cscf_orig_ioi_str.s = cscf_orig_ioi;
00535     cscf_orig_ioi_str.len = strlen(cscf_orig_ioi);
00536     
00537     cscf_term_ioi_str.s = cscf_term_ioi;
00538     cscf_term_ioi_str.len = strlen(cscf_term_ioi);
00539 
00540 
00541     /* Record-routes */
00542     pcscf_record_route_mo.s = pkg_malloc(s_record_route_s.len+s_mo.len+pcscf_name_str.len+s_record_route_e.len);
00543     if (!pcscf_record_route_mo.s){
00544         LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00545             s_record_route_s.len+s_mo.len+pcscf_name_str.len+s_record_route_e.len);
00546         return 0;
00547     }
00548     pcscf_record_route_mt.s = pkg_malloc(s_record_route_s.len+s_mt.len+pcscf_name_str.len+s_record_route_e.len);
00549     if (!pcscf_record_route_mt.s){
00550         LOG(L_ERR, "ERR"M_NAME":mod_init: Error allocating %d bytes\n",
00551             s_record_route_s.len+s_mt.len+pcscf_name_str.len+s_record_route_e.len);
00552         return 0;
00553     }
00554     
00555     pcscf_record_route_mo.len=0;
00556     STR_APPEND(pcscf_record_route_mo,s_record_route_s);
00557     if (pcscf_name_str.len>4 && strncasecmp(pcscf_name_str.s,"sip:",4)==0){
00558         STR_APPEND(pcscf_record_route_mo,s_mo);
00559         memcpy(pcscf_record_route_mo.s+pcscf_record_route_mo.len,pcscf_name_str.s+4,
00560             pcscf_name_str.len-4);
00561         pcscf_record_route_mo.len += pcscf_name_str.len-4;
00562     } else {
00563         STR_APPEND(pcscf_record_route_mo,s_mo);
00564         STR_APPEND(pcscf_record_route_mo,pcscf_name_str);
00565     }
00566     STR_APPEND(pcscf_record_route_mo,s_record_route_e);
00567     pcscf_record_route_mo_uri.s = pcscf_record_route_mo.s + s_record_route_s.len;
00568     pcscf_record_route_mo_uri.len = pcscf_record_route_mo.len - s_record_route_s.len - s_record_route_e.len;
00569 
00570     pcscf_record_route_mt.len=0;
00571     STR_APPEND(pcscf_record_route_mt,s_record_route_s);
00572     if (pcscf_name_str.len>4 && strncasecmp(pcscf_name_str.s,"sip:",4)==0){
00573         STR_APPEND(pcscf_record_route_mt,s_mt);
00574         memcpy(pcscf_record_route_mt.s+pcscf_record_route_mt.len,pcscf_name_str.s+4,
00575             pcscf_name_str.len-4);
00576         pcscf_record_route_mt.len += pcscf_name_str.len-4;
00577     } else {
00578         STR_APPEND(pcscf_record_route_mt,s_mt);
00579         STR_APPEND(pcscf_record_route_mt,pcscf_name_str);
00580     }
00581     STR_APPEND(pcscf_record_route_mt,s_record_route_e);
00582     pcscf_record_route_mt_uri.s = pcscf_record_route_mt.s + s_record_route_s.len;
00583     pcscf_record_route_mt_uri.len = pcscf_record_route_mt.len - s_record_route_s.len - s_record_route_e.len;
00584 
00585     /* fix the parameters */
00586     forced_clf_peer_str.s = forced_clf_peer;
00587     forced_clf_peer_str.len = strlen(forced_clf_peer);
00588     return 1;
00589 }
00590 
00591 db_con_t* create_pcscf_db_connection()
00592 {
00593     if (pcscf_persistency_mode!=WITH_DATABASE_BULK && pcscf_persistency_mode!=WITH_DATABASE_CACHE) return NULL;
00594     if (!pcscf_dbf.init) return NULL;
00595 
00596     return pcscf_dbf.init(pcscf_db_url);
00597 }
00598 
00602 static int mod_init(void)
00603 {
00604     load_tm_f load_tm;
00605     load_cdp_f load_cdp;
00606     bind_dlg_mod_f load_dlg;
00607             
00608     LOG(L_INFO,"INFO:"M_NAME":mod_init: Initialization of module\n");
00609     shutdown_singleton=shm_malloc(sizeof(int));
00610     *shutdown_singleton=0;
00611     
00612     
00613     /* fix the parameters */
00614     if (!fix_parameters()) goto error;
00615 
00616     #ifdef WITH_IMS_PM
00617         ims_pm_init(pcscf_name_str,ims_pm_node_type, ims_pm_logfile);
00618         ims_pm_init_pcscf();
00619     #endif /* WITH_IMS_PM */
00620     
00621     cscf_icid_value_count = shm_malloc(sizeof(unsigned int));
00622     *cscf_icid_value_count = 0;
00623     cscf_icid_value_count_lock = lock_alloc();
00624     cscf_icid_value_count_lock = lock_init(cscf_icid_value_count_lock);
00625     
00626     /* load the send_reply function from sl module */
00627     sl_reply = find_export("sl_send_reply", 2, 0);
00628     if (!sl_reply) {
00629         LOG(L_ERR, "ERR"M_NAME":mod_init: This module requires sl module\n");
00630         goto error;
00631     }
00632     
00633     if(pcscf_persistency_mode==WITH_DATABASE_BULK || pcscf_persistency_mode==WITH_DATABASE_CACHE){
00634         /* bind to the db module */
00635         if (!pcscf_db_url) {
00636             LOG(L_ERR, "ERR:"M_NAME":mod_init: no db_url specified but DB has to be used "
00637                 "(pcscf_persistency_mode=%d\n", pcscf_persistency_mode);
00638             return -1;
00639         }
00640         if (bind_dbmod(pcscf_db_url, &pcscf_dbf) < 0) { /* Find database module */
00641             LOG(L_ERR, "ERR"M_NAME":mod_init: Can't bind database module via url %s\n", pcscf_db_url);
00642             return -1;
00643         }
00644 
00645         if (!DB_CAPABILITY(pcscf_dbf, DB_CAP_ALL)) {
00646             LOG(L_ERR, "ERR:"M_NAME":mod_init: Database module does not implement all functions needed by the module\n");
00647             return -1;
00648         }
00649         
00650         pcscf_db = create_pcscf_db_connection();
00651         if (!pcscf_db) {
00652             LOG(L_ERR, "ERR:"M_NAME": mod_init: Error while connecting database\n");
00653             return -1;
00654         }
00655         
00656         /* db lock */
00657         db_lock = (gen_lock_t*)lock_alloc();
00658         if(!db_lock){
00659             LOG(L_ERR, "ERR:"M_NAME": mod_init: No memory left\n");
00660             return -1;
00661         }
00662         lock_init(db_lock);
00663     
00664         /* snapshot and step versions */
00665     
00666         subs_snapshot_version=(int*)shm_malloc(sizeof(int));
00667         if(!subs_snapshot_version){
00668             LOG(L_ERR, "ERR:"M_NAME":mod_init: subs_snapshot_version, no memory left\n");
00669             return -1;
00670         }
00671         *subs_snapshot_version=0;
00672     
00673         subs_step_version=(int*)shm_malloc(sizeof(int));
00674         if(!subs_step_version){
00675             LOG(L_ERR, "ERR:"M_NAME":mod_init: subs_step_version, no memory left\n");
00676             return -1;
00677         }
00678         *subs_step_version=0;
00679     
00680         dialogs_snapshot_version=(int*)shm_malloc(sizeof(int));
00681         if(!dialogs_snapshot_version){
00682             LOG(L_ERR, "ERR:"M_NAME":mod_init: dialogs_snapshot_version, no memory left\n");
00683             return -1;
00684         }
00685         *dialogs_snapshot_version=0;
00686     
00687         dialogs_step_version=(int*)shm_malloc(sizeof(int));
00688         if(!dialogs_step_version){
00689             LOG(L_ERR, "ERR:"M_NAME":mod_init: dialogs_step_version, no memory left\n");
00690             return -1;
00691         }
00692         *dialogs_step_version=0;
00693     
00694         registrar_snapshot_version=(int*)shm_malloc(sizeof(int));
00695         if(!registrar_snapshot_version){
00696             LOG(L_ERR, "ERR:"M_NAME":mod_init: registrar_snapshot_version, no memory left\n");
00697             return -1;
00698         }
00699         *registrar_snapshot_version=0;
00700     
00701         registrar_step_version=(int*)shm_malloc(sizeof(int));
00702         if(!registrar_step_version){
00703             LOG(L_ERR, "ERR:"M_NAME":mod_init: registrar_step_version, no memory left\n");
00704             return -1;
00705         }
00706         *registrar_step_version=0;  
00707     }
00708         
00709     /* bind to the tm module */
00710     if (!(load_tm = (load_tm_f)find_export("load_tm",NO_SCRIPT,0))) {
00711         LOG(L_ERR, "ERR:"M_NAME":mod_init: Can not import load_tm. This module requires tm module\n");
00712         goto error;
00713     }
00714     if (load_tm(&tmb) == -1)
00715         goto error;
00716 
00717     /* bind to the dialog module */
00718     load_dlg = (bind_dlg_mod_f)find_export("bind_dlg_mod", -1, 0);
00719     if (!load_dlg) {
00720         LOG(L_ERR, "ERR:"M_NAME":mod_init:  Can not import bind_dlg_mod. This module requires dialog module\n");
00721         return -1;
00722     }
00723     if (load_dlg(&dialogb) != 0) {
00724         return -1;
00725     }
00726 
00727     /* bind to the cdp module */
00728     if (pcscf_use_e2){
00729         if (!(load_cdp = (load_cdp_f)find_export("load_cdp",NO_SCRIPT,0))) {
00730             LOG(L_ERR, "DBG:"M_NAME":mod_init: Can not import load_cdp. This module requires cdp module.\n");
00731             
00732             LOG(L_ERR, "DBG:"M_NAME":mod_init: Usage of the e2 interface has been disabled.\n");            
00733             pcscf_use_e2 = 0;
00734         }
00735         if (load_cdp(&cdpb) == -1)
00736             goto error;
00737     }   
00738     
00739     /* init the registrar storage */
00740     if (!r_storage_init(registrar_hash_size)) goto error;
00741     if (pcscf_persistency_mode!=NO_PERSISTENCY){
00742         load_snapshot_registrar();
00743         if (register_timer(persistency_timer_registrar,0,pcscf_persistency_timer_registrar)<0) goto error;
00744     }
00745 
00746     /* register the registrar timer */
00747     if (register_timer(registrar_timer,registrar,10)<0) goto error;
00748     
00749     /* init the registrar subscriptions */
00750     if (!r_subscription_init()) goto error;
00751     if (pcscf_persistency_mode!=NO_PERSISTENCY){
00752         load_snapshot_subscriptions();
00753         if (register_timer(persistency_timer_subscriptions,0,pcscf_persistency_timer_subscriptions)<0) goto error;
00754     }
00755 
00756     /* register the subscription timer */
00757     if (register_timer(subscription_timer,registrar,10)<0) goto error;
00758     
00759     /* init the dialog storage */
00760     if (!p_dialogs_init(pcscf_dialogs_hash_size)){
00761         LOG(L_ERR, "ERR"M_NAME":mod_init: Error initializing the Hash Table for stored dialogs\n");
00762         goto error;
00763     }       
00764     pcscf_dialog_count = shm_malloc(sizeof(int));
00765     *pcscf_dialog_count = 0;
00766     pcscf_dialog_count_lock = lock_alloc();
00767     pcscf_dialog_count_lock = lock_init(pcscf_dialog_count_lock);
00768 
00769     if (pcscf_persistency_mode!=NO_PERSISTENCY){
00770         load_snapshot_dialogs();
00771         if (register_timer(persistency_timer_dialogs,0,pcscf_persistency_timer_dialogs)<0) goto error;
00772     }
00773 
00774     /* register the dialog timer */
00775     if (register_timer(dialog_timer,p_dialogs,60)<0) goto error;
00776     
00777     if (pcscf_nat_enable)
00778         if(!nat_prepare_1918addr()) goto error;
00779 
00780     /* rtp proxy initilazition */
00781     if (pcscf_nat_enable && rtpproxy_enable) 
00782         if (!rtpproxy_init()) goto error;
00783 
00784     if (pcscf_use_tls)
00785     {
00786         get_tls_session_hash = (void *)find_export("get_tls_session_hash", 0, 0);
00787         if (! get_tls_session_hash) {
00788             LOG(L_ERR,"ERR:"M_NAME":mod_init: get_tls_session_hash not found !\n");
00789             goto error;
00790         }
00791     }
00792     return 0;
00793 error:
00794     return -1;
00795 }
00796 
00797 extern gen_lock_t* process_lock;        /* lock on the process table */
00798 
00799 void close_pcscf_db_connection(db_con_t* db)
00800 {
00801     if (db && pcscf_dbf.close) pcscf_dbf.close(db);
00802 }
00803 
00807 static int mod_child_init(int rank)
00808 {
00809     LOG(L_INFO,"INFO:"M_NAME":mod_init: Initialization of module in child [%d] \n",
00810         rank);
00811     /* don't do anything for main process and TCP manager process */
00812     if ( rank == PROC_MAIN || rank == PROC_TCP_MAIN )
00813         return 0;
00814             
00815     /* Init the user data parser */
00816     if (!parser_init(pcscf_reginfo_dtd)) return -1;
00817         
00818 
00819     /* rtpproxy child init */
00820     if (pcscf_nat_enable && rtpproxy_enable) 
00821         if (!rtpproxy_child_init(rank)) return -1;
00822 
00823     return 0;
00824 }
00825 
00829 static void mod_destroy(void)
00830 {
00831     int do_destroy=0;
00832     LOG(L_INFO,"INFO:"M_NAME":mod_destroy: child exit\n");
00833     lock_get(process_lock);
00834         if((*shutdown_singleton)==0){
00835             *shutdown_singleton=1;
00836             do_destroy=1;
00837         }
00838     lock_release(process_lock);
00839     if (do_destroy){
00840         if (pcscf_persistency_mode!=NO_PERSISTENCY){        
00841             /* First let's snapshot everything */
00842             make_snapshot_dialogs();
00843             make_snapshot_registrar();
00844             make_snapshot_subscriptions();
00845         }
00846         /* Then nuke it all */      
00847         parser_destroy();
00848         r_subscription_destroy();
00849         r_storage_destroy();
00850         p_dialogs_destroy();
00851         lock_get(pcscf_dialog_count_lock);
00852         shm_free(pcscf_dialog_count);
00853         lock_destroy(pcscf_dialog_count_lock);
00854     }
00855     
00856     if ( (pcscf_persistency_mode==WITH_DATABASE_BULK || pcscf_persistency_mode==WITH_DATABASE_CACHE) && pcscf_db) {
00857         DBG("INFO:"M_NAME": ... closing db connection\n");
00858         close_pcscf_db_connection(pcscf_db);
00859     }
00860     pcscf_db = NULL;
00861 
00862     #ifdef WITH_IMS_PM
00863         ims_pm_destroy();   
00864     #endif /* WITH_IMS_PM */        
00865 }
00866 
00867 
00875 int P_trans_in_processing(struct sip_msg* msg, char* str1, char* str2)
00876 {
00877     unsigned