[Overview] [Code Structure] [Configuration and usage] [Example]
To use it you need the The CDiameterPeer Module (cdp) loaded. This is because this module communicates using Diameter with the Home Subscriber Server over the IMS_Cx inteface.
# # $Id: scscf.cfg 571 2008-07-02 12:00:17Z vingarzan $ # # Serving - CSCF configuration script # # ----------- global configuration parameters ------------------------ debug=3 log_stderror=yes memlog=5 sip_warning=yes fork=yes children=4 listen=127.0.0.1 port=6060 alias=scscf.open-ims.test:6060 check_via=no # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) # ------------------ module loading ---------------------------------- loadmodule "/opt/OpenIMSCore/ser_ims/modules/sl/sl.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/tm/tm.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/dialog/dialog.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/rr/rr.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/maxfwd/maxfwd.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/textops/textops.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/enum/enum.so" loadmodule "/opt/OpenIMSCore/ser_ims/modules/scscf/scscf.so" modparam("scscf","name","sip:scscf.open-ims.test:6060") #Comment the following line to allow for realm routing on the Cx interface #modparam("scscf","forced_hss_peer","hss.open-ims.test") modparam("scscf","auth_data_hash_size",64) modparam("scscf","auth_vector_timeout",60) modparam("scscf","auth_data_timeout",60) modparam("scscf","av_request_at_once",1) modparam("scscf","av_request_at_sync",1) modparam("scscf","server_assignment_store_data",0) # only one of user_data validation file should normaly be declared here # because if both are specified the data will be checked twice #modparam("scscf","user_data_dtd","/opt/OpenIMSCore/ser_ims/modules/scscf/CxDataType.dtd") modparam("scscf","user_data_xsd","/opt/OpenIMSCore/ser_ims/modules/scscf/CxDataType_Rel7.xsd") modparam("scscf","registrar_hash_size",256) modparam("scscf","registration_default_expires",3600) modparam("scscf","registration_min_expires",30) modparam("scscf","registration_max_expires",1000000) modparam("scscf","registration_default_algorithm","AKAv1-MD5") #modparam("scscf","registration_default_algorithm","AKAv2-MD5") #modparam("scscf","registration_default_algorithm","MD5") #modparam("scscf","registration_default_algorithm","CableLabs-Digest") #modparam("scscf","registration_default_algorithm","TISPAN-HTTP_DIGEST_MD5") # Let the HSS decide #modparam("scscf","registration_default_algorithm","HSS-Selected") # The next authentication methods are implemented here but not yet completed in FHoSS # please do not complain about bugs when using with FHoSS, yet! #modparam("scscf","registration_default_algorithm","NASS-Bundled") modparam("scscf","registration_disable_early_ims",1) modparam("scscf","registration_disable_nass_bundled",1) modparam("scscf","subscription_default_expires",3600) modparam("scscf","subscription_min_expires",30) modparam("scscf","subscription_max_expires",1000000) modparam("scscf","dialogs_hash_size",256) modparam("scscf","dialogs_expiration_time",3600) modparam("scscf","dialogs_enable_release",1) modparam("scscf","max_dialog_count",20000) modparam("scscf","min_se",90) # persistency_mode - 0 None / 1 Files / 2 Databases modparam("scscf","persistency_mode",0) # support for wildcard PSI 0 No 1 Yes modparam("scscf","support_wildcardPSI",0) #modparam("scscf","persistency_mode",1) #modparam("scscf","persistency_location","/opt/OpenIMSCore/persistency") #modparam("scscf","persistency_timer_authdata",60) #modparam("scscf","persistency_timer_dialogs",60) #modparam("scscf","persistency_timer_registrar",60) loadmodule "/opt/OpenIMSCore/ser_ims/modules/isc/isc.so" modparam("isc","my_uri","scscf.open-ims.test:6060") modparam("isc","isc_fr_timeout",5000) modparam("isc","isc_fr_inv_timeout",20000) modparam("isc","expires_grace",120) loadmodule "/opt/OpenIMSCore/ser_ims/modules/cdp/cdp.so" modparam("cdp","config_file","/opt/OpenIMSCore/scscf.xml") # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1) # ------------------------- request routing logic ------------------- # main routing logic route{ route(Sanity_Checks); # don't repeat work for a transaction already in processing if (method!="ACK" && S_trans_in_processing()) { log(1,"Trans already in processing... skip\n"); break; } if (method=="REGISTER") { route(REGISTER); break; } if (method=="SUBSCRIBE" && search("^(Event|o)([ \t]*):([ \t]*)reg")) { route(SUBSCRIBE); break; } if (method=="ACK") { loose_route(); t_relay(); exit; } if (S_mobile_originating()||ISC_from_AS("orig")){ # support for AS origination on behalf of unregistered user if (S_orig_not_registered()) { S_assign_server_unreg("open-ims.test", "orig"); } # Originating route(Orig); break; }else{ if (S_is_in_dialog("orig")){ route(Orig_Subsequent); break; } if (S_is_in_dialog("term")){ route(Term_Subsequent); break; } # Terminating if (uri=~"sip:(.*)@open-ims\.test(.*)" || uri=~"tel:.*"){ if (S_term_not_registered()) S_assign_server_unreg("open-ims.test", "term"); }else{ sl_send_reply("403","Forbidden - Dialog not found on S-CSCF or Terminating user not suitable for unregistered services"); exit(); } route(Term); break; } } route[Sanity_Checks] { # initial sanity checks -- messages with # max_forwards==0, or excessively long requests if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }; if (msg:len >= max_len ) { sl_send_reply("513", "Message too big"); exit; }; if(@hf_value.max_forwards=="0"){ exit; } } route[Check_Session_Expires] { if (!S_check_session_expires()) { S_422_session_expires(); exit; }; } route[REGISTER] { if (uri=~"sip:(.*)open-ims\.test(.*)"){ t_newtran(); # if ( !t_newtran()) { # sl_reply_error(); # break; # }; if (!S_is_integrity_protected("open-ims.test")){ # Unprotected REGISTER # Variant 1 - accept also non IPSec clients if (!S_is_authorized("open-ims.test")) { S_challenge("open-ims.test"); route(Service_Routes); t_reply("401", "Unauthorized - Challenging the UE"); exit; }else{ if (S_is_not_registered()){ if (S_assign_server("open-ims.test")){ route(Service_Routes); route(Charging_Function_Addresses); t_reply("200","OK - SAR succesful and registrar saved"); ISC_match_filter_reg("0"); exit; }else{ t_reply("500","Server Internal Error - Server Assignment failed"); exit; } }else{ ISC_match_filter_reg("1"); if (S_assign_server("open-ims.test")){ route(Service_Routes); route(Charging_Function_Addresses); t_reply("200","OK - SAR succesful and registrar saved"); exit; }else{ t_reply("500","Server Internal Error - Server Assignment failed"); exit; } } } # Variant 2 - accept only IPSec clients #S_challenge("open-ims.test"); #route(Service_Routes); #t_reply("401", "Unauthorized - Challenging the UE"); break; }else{ # Protected REGISTER # Variant 1 - Always require reauthentication #if (!S_is_authorized("open-ims.test")) { # S_challenge("open-ims.test"); # route(Service_Routes); # t_reply("401", "Unauthorized - Challenging the UE"); # exit; #} # Variant 2 - trust protected REGISTER if (S_is_not_registered()){ if (S_assign_server("open-ims.test")){ route(Service_Routes); route(Charging_Function_Addresses); t_reply("200","OK - SAR succesful and registrar saved"); ISC_match_filter_reg("0"); exit; }else{ t_reply("500","Server Internal Error - Server Assignment failed"); exit; } }else{ ISC_match_filter_reg("1"); if (S_assign_server("open-ims.test")){ route(Service_Routes); route(Charging_Function_Addresses); t_reply("200","OK - SAR succesful and registrar saved"); exit; }else{ t_reply("500","Server Internal Error - Update Contacts failed"); exit; } } } } else { sl_send_reply("403", "Forbidden - Domain not serviced"); } } route[Service_Routes] { # if (!S_check_visited_network_id("open-ims\.test")){ # S_add_service_route("sip:thig@icscf.open-ims.test"); # } S_add_path_service_routes(); S_add_allow("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, PUBLISH, MESSAGE, INFO"); } route[Charging_Function_Addresses] { if (S_check_visited_network_id("open-ims\.test")){ S_add_p_charging_function_addresses(); } } route[SUBSCRIBE] { if ( !t_newtran()) { sl_reply_error(); break; } if (!S_term_registered()){ t_reply("404","Not Found - User not registered on this S-CSCF"); exit; } if (S_can_subscribe()){ if (S_subscribe()){ # This is replied from S_subscribe, as that also add extra headers #t_reply("200","OK - Subscription saved"); exit; }else{ t_reply("500","Server Error saving subscription"); exit; } }else{ t_reply("403","Forbidden to SUBSCRIBE"); exit; }; } # ORIGINATING route[Orig] { log(1,">> Orig\n"); if (S_originating_barred()){ sl_send_reply("403","Forbidden - Originating Public Identity barred"); exit; } if (method=="INVITE"||method=="SUBSCRIBE"){ route(Check_Session_Expires); if (!S_is_record_routed("orig")) S_record_route("orig"); if (!S_save_dialog("orig")){ sl_send_reply("514","Originating dialog save failure - S-CSCF maximum dialog count reached!"); exit; } } loose_route(); S_privacy_hook(); # check if dialog saved as fwded to AS if (ISC_match_filter("orig")){ t_on_reply("ISC_Orig_reply"); t_on_failure("ISC_Orig_failure"); log(1,">> Orig - msg was fwded to AS\n"); exit; } # if THIG_required -> add THIG route if (!ISC_from_AS("orig")){ S_add_p_asserted_identity(); } if (method=="INVITE") { route(PSTN_handling); } t_on_reply("Orig_reply"); #t_on_failure("Orig_failure"); # Do not loop through the I-CSCF if the terminating user is here # might not work if other routes are present if (S_term_registered()){ t_relay_to_udp("127.0.0.1",6060); exit; } if (!t_relay()) { sl_send_reply("500","Error forwarding towards terminating leg"); exit; }; } onreply_route[Orig_reply] { log(1,">> Orig_reply\n"); if (!S_update_dialog("orig")){ log(1,">> Error updating orig dialog - maybe non-dialog request...\n"); } } failure_route[Orig_failure] { log(1,">> Orig_failure\n"); } onreply_route[ISC_Orig_reply] { log(1,">> ISC_Orig_reply\n"); if (!S_update_dialog("orig")){ log(1,">> Error updating orig dialog - maybe non-dialog request...\n"); } break; } failure_route[ISC_Orig_failure] { log(1,">> ISC_Orig_failure\n"); # if (t_check_status("408")) { # if (ISC_is_session_continued()){ # log(1,">> ISC continue session not implemented :(\n"); # break; # }else{ # t_reply("555","AS failed to respond"); # } # } if (t_check_status("408")||t_check_status("5..")){ t_on_reply("ISC_Orig_reply"); t_on_failure("ISC_Orig_failure"); if (ISC_match_filter("orig")){ log(1,">> ISC_Orig_failure - msg was fwded to AS\n"); exit; } # if THIG_required -> add THIG route if (!ISC_from_AS("origfail")){ S_add_p_asserted_identity(); } if (method=="INVITE") { route(PSTN_handling); } t_on_reply("Orig_reply"); t_on_failure("Orig_failure"); # Do not loop through the I-CSCF if the terminating user is here # might not work if other routes are present if (S_term_registered()){ append_branch(); t_relay_to_udp("127.0.0.1",6060); exit; } if (!t_relay()) { append_branch(); if (!t_relay()) { t_reply("500","Error forwarding towards terminating leg"); exit; } }; } } route[Orig_Subsequent] { log(1,">> Orig_Subsequent\n"); loose_route(); if (method=="INVITE"){ route(Check_Session_Expires); S_update_dialog("orig"); } #S_record_route("orig"); if (method!="ACK"){ S_privacy_hook(); t_on_reply("Orig_Subsequent_reply"); #t_on_failure("Orig_Subsequent_failure"); } if (!t_relay()) { sl_send_reply("500","Error forwarding subsequent request towards terminating leg"); exit; }; } onreply_route[Orig_Subsequent_reply] { log(1,">> Orig_Subsequent_reply\n"); # if (t_check_status("305")){ # S_proxy_request(); # break; # } S_update_dialog("orig"); break; } failure_route[Orig_Subsequent_failure] { log(1,">> Orig_Subsequent_failure\n"); } # TERMINATING route[Term] { log(1,">> Term\n"); if (S_terminating_barred()){ sl_send_reply("404","Not Found - Terminating user barred"); exit; } if (method=="INVITE"||method=="SUBSCRIBE"){ route(Check_Session_Expires); if (!S_is_record_routed("term")) S_record_route("term"); if (!S_save_dialog("term")){ sl_send_reply("514","Terminating dialog save failure - S-CSCF maximum dialog count reached!"); exit; } } loose_route(); # check if dialog saved as fwded to AS if (ISC_match_filter("term")){ t_on_reply("ISC_Term_reply"); t_on_failure("ISC_Term_failure"); log(1,">> Term - msg was fwded to AS\n"); exit; } if (!S_lookup()){ if (uri=~"sip:(.*)@open-ims\.test(.*)") { if ( !t_newtran()) { sl_reply_error(); exit; }; t_reply("404","Not Found - destination user not found on this S-CSCF"); exit; } } t_on_reply("Term_reply"); #t_on_failure("Term_failure"); S_apply_privacy(); if (!t_relay()) { sl_send_reply("500","Error forwarding towards terminating leg"); exit; }; } onreply_route[Term_reply] { log(1,">> Term_reply\n"); if (!S_update_dialog("term")){ log(1,">> Error updating term dialog - maybe non-dialog request...\n"); } } failure_route[Term_failure] { log(1,">> Term_failure\n"); } onreply_route[ISC_Term_reply] { log(1,">> ISC_Term_reply\n"); if (!S_update_dialog("term")){ log(1,">> Error updating term dialog - maybe non-dialog request...\n"); } break; } failure_route[ISC_Term_failure] { log(1,">> ISC_Term_failure\n"); # if (t_check_status("408")) { # if (ISC_is_session_continued()){ # log(1,">> ISC continue session not implemented :(\n"); # break; # }else{ # t_reply("555","AS failed to respond"); # } # } if (t_check_status("408")||t_check_status("5..")){ t_on_reply("ISC_Term_reply"); t_on_failure("ISC_Term_failure"); if (ISC_match_filter("term")){ log(1,">> Term - msg was fwded to AS\n"); exit; } if (!S_lookup()){ if (uri=~"sip:(.*)@open-ims\.test(.*)") { #if ( !t_newtran()) { # sl_reply_error(); # exit; #}; t_reply("404","Not Found - destination user not found on this S-CSCF"); exit; } } t_on_reply("Term_reply"); t_on_failure("Term_failure"); if (!t_relay()) { append_branch(); if (!t_relay()) { t_reply("500","Error forwarding towards terminating leg"); exit; } }; } } route[Term_Subsequent] { log(1,">> Term_Subsequent\n"); loose_route(); if (method=="INVITE"){ route(Check_Session_Expires); S_update_dialog("term"); } S_apply_privacy(); #S_record_route("term"); if (method!="ACK") { t_on_reply("Term_Subsequent_reply"); #t_on_failure("Term_Subsequent_failure"); } if (!t_relay()) { sl_send_reply("500","Error forwarding subsequent request towards user"); exit; }; } onreply_route[Term_Subsequent_reply] { log(1,">> Term_Subsequent_reply\n"); # if (t_check_status("305")){ # S_proxy_request(); # break; # } S_update_dialog("term"); break; } failure_route[Term_Subsequent_failure] { log(1,">> Term_Subsequent_failure\n"); } route[PSTN_handling] { #PSTN gateway handling if (uri=~"tel:\+(.*)"){ if(!enum_query()){ route(PSTN); break; } } #if (uri=~"sip:[0-9]+@open-ims\.test(.*)"){ # route(PSTN); # break; #} # a tel URI in non-international format (i.e. the local service number analysis and handling is either failed in the appropriate AS or the request has not been forwarded to AS for local service number analysis and handling at all) if (uri=~"tel:[^+]*") { route(PSTN); break; } # a SIP URI with the user part starting with a + and user=phone if (uri=~"sip:\+[0-9]+@open-ims\.test.*user=phone.*"){ route(PSTN); break; } } route[PSTN] { t_on_reply("PSTN_reply"); t_relay_to_udp("127.0.0.1", "9060"); exit; } onreply_route[PSTN_reply] { log(1,">> PSTN_reply\n"); if (!S_update_dialog("orig")){ log(1,">> Error updating orig dialog - maybe non-dialog request...\n"); } }
1.5.2