[Overview] [Code Structure] [Configuration and usage] [Example]
# # $Id: pcscf.cfg 578 2008-08-25 15:21:55Z vingarzan $ # # Proxy - 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=4060 # Uncomment here to enable TLS! #listen=tls:127.0.0.1 #tls_port_no=4061 #enable_tls=yes alias=pcscf.open-ims.test:4060 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/pcscf/pcscf.so" modparam("pcscf","name","sip:pcscf.open-ims.test:4060") modparam("pcscf","registrar_hash_size",256) modparam("pcscf","reginfo_dtd","/opt/OpenIMSCore/ser_ims/modules/pcscf/reginfo.dtd") modparam("pcscf","subscriptions_hash_size",256) modparam("pcscf","dialogs_hash_size",256) modparam("pcscf","dialogs_expiration_time",3600) modparam("pcscf","dialogs_enable_release",1) modparam("pcscf","max_dialog_count",20000) modparam("pcscf","min_se",90) modparam("pcscf","use_ipsec",1) modparam("pcscf","ipsec_host","127.0.0.1") modparam("pcscf","ipsec_port_c",4060) modparam("pcscf","ipsec_port_s",4060) # Comment here to enable TLS! modparam("pcscf","use_tls",0) # Uncomment here to enable TLS! #modparam("pcscf","use_tls",1) #modparam("pcscf","tls_port",4061) modparam("pcscf","ipsec_P_Inc_Req","/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Inc_Req.sh") modparam("pcscf","ipsec_P_Out_Rpl","/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Out_Rpl.sh") modparam("pcscf","ipsec_P_Out_Req","/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Out_Req.sh") modparam("pcscf","ipsec_P_Inc_Rpl","/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Inc_Rpl.sh") modparam("pcscf","ipsec_P_Drop","/opt/OpenIMSCore/ser_ims/modules/pcscf/ipsec_P_Drop.sh") modparam("pcscf","NAT_enable", 1) modparam("pcscf","ping", 1) modparam("pcscf","ping_all", 0) modparam("pcscf","nat_detection_type", 0x17) modparam("pcscf","rtpproxy_socket", "udp:127.0.0.1:34999") modparam("pcscf","rtpproxy_enable", 0) modparam("pcscf","rtpproxy_disable_tout", 60) modparam("pcscf","rtpproxy_retr", 5) modparam("pcscf","rtpproxy_tout", 1) modparam("pcscf","subscribe_retries", 1) modparam("pcscf","icid_value_prefix","P-CSCFabcd") modparam("pcscf","icid_gen_addr","127.0.0.1") modparam("pcscf","orig_ioi","open-ims.test") modparam("pcscf","term_ioi","open-ims.test") # persistency_mode - 0 None / 1 Files / 2 Databases modparam("pcscf","persistency_mode",0) #modparam("pcscf","persistency_mode",1) #modparam("pcscf","persistency_location","/opt/OpenIMSCore/persistency") #modparam("pcscf","persistency_timer_dialogs",60) #modparam("pcscf","persistency_timer_registrar",60) #modparam("pcscf","persistency_timer_subscriptions",60) # e2 Interface configuration (NASS-Bundled Authentication) #modparam("pcscf","forced_clf_peer","clf.open-ims.test") modparam("pcscf","use_e2",0) # Uncomment here to enable the e2 interface (NASS-Bundled Authentication) #loadmodule "/opt/OpenIMSCore/ser_ims/modules/cdp/cdp.so" #modparam("cdp", "config_file", "/opt/OpenIMSCore/pcscf.xml") # -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1) # Uncomment here to enable TLS! #loadmodule "/opt/OpenIMSCore/ser_ims/modules/tls/tls.so" #modparam("tls", "tls_method", "TLSv1") #modparam("tls", "private_key", "/opt/OpenIMSCore/PCSCF_CA/pcscf_private_key.pem") #modparam("tls", "certificate", "/opt/OpenIMSCore/PCSCF_CA/pcscf_cert.pem") #modparam("tls", "ca_list", "/opt/OpenIMSCore/PCSCF_CA/pcscf_ca_list.pem") #modparam("tls", "verify_certificate", 1) #modparam("tls", "require_certificate", 0) #modparam("tls", "tls_disable_compression", 1) # ------------------------- request routing logic ------------------- # main routing logic route{ route(Sanity_Checks); force_rport(); # Early-IMS checks if (!P_check_via_sent_by()){ P_add_via_received(); } if (method=="REGISTER") { route(REGISTER); break; } # Only allow REGISTER as unprotected message # else { # if (!P_is_integrity_protected()){ # append_to_reply("Proxy-Require: sec-agree\r\n"); # sl_send_reply("494","Security Agreement Required"); # exit; # } # } if (method=="NOTIFY"&&uri==myself){ route(NOTIFY); break; } if (!P_mobile_terminating()){ # Request Initiated by the UE if (P_is_in_dialog("orig")){ if (method!="CANCEL") route(Orig_Subsequent); else route(Orig_Standalone); break; } if (P_is_in_dialog("term")){ if (method!="CANCEL") route(Term_Subsequent); else route(Orig_Standalone); break; } # No dialog yet - ACK not relayed as hop-to-hop if (method=="ACK"){ t_release(); break; }else if (method=="INVITE" || method=="SUBSCRIBE"){ route(Orig_Initial); break; }else{ if (method=="UPDATE"){ sl_send_reply("403","Forbidden - Target refresh outside dialog not allowed"); break; } if (method=="BYE" || method=="PRACK"){ sl_send_reply("403","Forbidden - Originating subsequent requests outside dialog not allowed"); break; } route(Orig_Standalone); break; } }else{ # TODO - check if this does come from an UE and that UE is unregistered # Request Terminated by the UE if (!P_is_in_dialog("term") && (method=="INVITE" || method=="SUBSCRIBE")){ route(Term_Initial); break; } else { if (P_is_in_dialog("term")){ if (method!="CANCEL") route(Term_Subsequent); else route(Term_Standalone); break; }else{ if (method==UPDATE){ sl_send_reply("403","Forbidden - Target refresh outside dialog not allowed"); break; } if (method=="BYE" || method=="ACK" || method=="PRACK"){ sl_send_reply("403","Forbidden - Terminating subsequent requests outside dialog not allowed"); break; } route(Term_Standalone); break; } } 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 (!P_check_session_expires()) { P_422_session_expires(); exit; }; } route[REGISTER_494] { append_to_reply("Proxy-Require: sec-agree\r\n"); t_reply("494","Security Agreement Required"); } route[REGISTER] { t_newtran(); if (!P_verify_security()) { route(REGISTER_494); break; }; if (!P_is_integrity_protected()){ #Variant 1 - accept also non IPSec clients P_remove_security_client(); #Variant 2 - accept only IPSec clients #if (!P_remove_security_client()){ # route(REGISTER_494); # break; #} P_add_integrity_protected("no"); }else{ if (!P_remove_security_verify()||!P_remove_security_client()){ route(REGISTER_494); break; } P_add_integrity_protected("yes"); }; P_remove_header_tag("Require","sec-agree"); P_remove_header_tag("Proxy-Require","sec-agree"); P_remove_security_verify(); P_add_path(); P_add_require(); P_add_p_charging_vector(); P_add_p_visited_network_id("open-ims.test"); # trigger the UDR on the e2 interface (NASS-Bundled Authentication) P_access_network_info("open-ims.test"); t_on_reply("REGISTER_reply"); t_on_failure("REGISTER_failure"); if (!t_relay()) { sl_send_reply("500","Error forwarding to Home Domain"); break; }; } onreply_route[REGISTER_reply] { #log(-1,"Got a response for REGISTER!!!\n"); if (t_check_status("401")){ if (!P_remove_ck_ik()){ # t_reply("500","P-CSCF Error on hiding CK, IK"); break; } P_security_401(); } if (t_check_status("200")){ if (!P_save_location()){ # t_reply("500","P-CSCF Error on saving location"); break; } P_security_200(); P_subscribe(); } if (!P_security_relay()) P_NAT_relay(); exit; } failure_route[REGISTER_failure] { #log(-1,"Got a failure for REGISTER!!!\n"); if (t_check_status("408")) t_reply("504","Server Time-Out"); } route[NOTIFY] { if ( !t_newtran()) { sl_reply_error(); break; } if (P_process_notification()) { t_reply("200","OK - P-CSCF processed notification"); break; }else{ t_reply("500","Error encountered while processing notification"); break; } } ####### ORIGINATING route[Orig_Initial] { log(1,">> Orig_Initial\n"); if (!P_is_registered()){ sl_send_reply("403","Forbidden - Not Registered! You must register first with a S-CSCF"); break; }; if (!P_assert_identity()){ sl_send_reply("403","Forbidden - You must register first with a S-CSCF"); break; }; # add IBCF/THIG route here if required loose_route(); if (!P_follows_service_routes()){ #Variant 1 - deny access to the network sl_send_reply("400","Bad Request - Not following indicated Service-Routes"); break; #Variant 2 - enforce routes and let the dialog continue #P_enforce_service_routes(); } P_record_route("orig"); P_remove_header_tag("Require","sec-agree"); P_remove_header_tag("Proxy-Require","sec-agree"); P_remove_security_verify(); P_add_p_charging_vector(); route(Check_Session_Expires); if (!P_save_dialog("orig")){ sl_send_reply("514","Originating dialog save failure - P-CSCF maximum dialog count reached!"); exit; } if (method=="INVITE"){ P_SDP_manipulate(); } t_on_reply("Orig_Initial_reply"); #t_on_failure("Orig_Initial_failure"); if (!t_relay()) { sl_send_reply("500","Error forwarding originating initial request"); break; }; } onreply_route[Orig_Initial_reply] { log(1,">> Orig_Initial_reply\n"); if (!t_check_status("1..")||t_check_status("180")||t_check_status("183")){ P_SDP_manipulate(); } if (!t_check_status("408")&&!t_check_status("480")){ P_update_dialog("orig"); }else{ P_drop_dialog("orig"); } if (!P_security_relay()) P_NAT_relay(); break; } failure_route[Orig_Initial_failure] { log(1,">> Orig_Initial_failure\n"); if (t_check_status("408")||t_check_status("480")){ P_drop_dialog("orig"); break; } #if (method=="INVITE") # P_drop_session(); #P_drop_dialog(); break; } route[Orig_Subsequent] { log(1,">> Orig_Subsequent\n"); if (P_is_registered()){ if (!P_assert_identity()){ sl_send_reply("403","Forbidden - You must register first with a S-CSCF"); break; }; } # else{ # let it continue as this probably does not come from an UE #sl_send_reply("403","Forbidden - Not Registered! You must register first with a S-CSCF"); #break; # } loose_route(); if (method!="CANCEL" && !P_follows_dialog_routes("orig")){ log(1,">> Orig_Subsequent: Request not following indicated dialog routes\n"); #Variant 1 - deny access to the network if (method!=ACK){ sl_send_reply("400","Bad Request - Not following indicated dialog routes"); } else{ log(1,">> Orig_Subsequent: ACK not following dialog routes discarded silently!!!\n"); } break; #Variant 2 - enforce routes and let the dialog continue #P_enforce_dialog_routes("term"); #break; } #P_record_route("orig"); route(Check_Session_Expires); P_update_dialog("orig"); if (method=="ACK" || method=="BYE"){ P_SDP_manipulate(); } P_remove_header_tag("Require","sec-agree"); P_remove_header_tag("Proxy-Require","sec-agree"); P_remove_security_verify(); # reply routes unused as empty at the moment t_on_reply("Orig_Subsequent_reply"); #t_on_failure("Orig_Subsequent_failure"); if (!t_relay()) { sl_send_reply("500","Error forwarding originating subsequent request"); break; }; } onreply_route[Orig_Subsequent_reply] { log(1,">> Orig_Subsequent_reply\n"); if (t_check_status("1..")||t_check_status("2..")){ P_update_dialog("orig"); # P_replace_contact();??? } if (!P_security_relay()) P_NAT_relay(); break; } failure_route[Orig_Subsequent_failure] { log(1,">> Orig_Subsequent_failure\n"); break; } route[Orig_Standalone] { log(1,">> Orig_Standalone\n"); if (!P_is_registered()){ sl_send_reply("403","Forbidden - Not Registered! You must register first with a S-CSCF"); break; }; if (!P_assert_identity()){ sl_send_reply("403","Forbidden - You must register first with a S-CSCF"); break; }; loose_route(); if (!P_follows_service_routes()){ #Variant 1 - deny access to the network sl_send_reply("400","Bad Request - Not following indicated service routes"); break; #Variant 2 - enforce routes and let the dialog continue #P_enforce_service_routes(); } # add IBCF/THIG route here if required P_remove_header_tag("Require","sec-agree"); P_remove_header_tag("Proxy-Require","sec-agree"); P_remove_security_verify(); P_add_p_charging_vector(); # reply routes unused as empty at the moment t_on_reply("Orig_Standalone_reply"); #t_on_failure("Orig_Standalone_failure"); if (!t_relay()) { sl_send_reply("500","Error forwarding originating standalone request"); break; }; } onreply_route[Orig_Standalone_reply] { log(1,">> Orig_Standalone_reply\n"); #P_store_charging(); if (!P_security_relay()) P_NAT_relay(); break; } failure_route[Orig_Standalone_failure] { log(1,">> Orig_Standalone_failure\n"); break; } ####### TERMINATING route[Term_Initial] { log(1,">> Term_Initial\n"); P_record_route("term"); route(Check_Session_Expires); if (!P_save_dialog("term")){ sl_send_reply("514","Terminating dialog save failure - P-CSCF maximum dialog count reached!"); exit; } loose_route(); t_on_reply("Term_Initial_reply"); #t_on_failure("Term_Initial_failure"); if (method=="INVITE") { P_SDP_manipulate(); } if (!P_security_relay()) P_NAT_relay(); t_on_reply("Term_Initial_reply"); #t_on_failure("Term_Initial_failure"); if (!t_relay()) { sl_send_reply("500","Error forwarding terminating initial request"); break; }; } onreply_route[Term_Initial_reply] { log(1,">> Term_Initial_reply\n"); if (!t_check_status("1..")||t_check_status("180")||t_check_status("183")){ P_SDP_manipulate(); } if (!P_follows_via_list()) { log(1,">> P_follows_via_list - failed"); P_enforce_via_list(); }; if (!t_check_status("408")&&!t_check_status("480")){ P_assert_called_identity(); P_update_dialog("term"); break; }else{ P_drop_dialog("term"); break; } } failure_route[Term_Initial_failure] { log(1,">> Term_Initial_failure\n"); if (!P_follows_via_list()) { log(1,">> P_follows_via_list - failed - this is a bug in P_follows_via_list()!\n"); # P_enforce_via_list(); }; if (t_check_status("408")||t_check_status("480")){ P_drop_dialog("term"); break; } break; } route[Term_Subsequent] { log(1,">> Term_Subsequent\n"); route(Check_Session_Expires); P_update_dialog("term"); loose_route(); #P_record_route("term"); if (method=="ACK" || method=="BYE"){ P_SDP_manipulate(); } P_remove_header_tag("Require","sec-agree"); P_remove_header_tag("Proxy-Require","sec-agree"); P_remove_security_verify(); t_on_reply("Term_Subsequent_reply"); #t_on_failure("Term_Subsequent_failure"); if (!P_security_relay()) P_NAT_relay(); if (!t_relay()) { sl_send_reply("500","Error forwarding terminating subsequent request"); break; }; } onreply_route[Term_Subsequent_reply] { log(1,">> Term_Subsequent_reply\n"); if (!P_follows_via_list()) { log(1,">> P_follows_via_list - failed\n"); P_enforce_via_list(); }; if (t_check_status("1..")||t_check_status("2..")){ P_update_dialog("term"); } break; } failure_route[Term_Subsequent_failure] { log(1,">> Term_Subsequent_failure\n"); if (!P_follows_via_list()) { log(1,">> P_follows_via_list - failed\n"); P_enforce_via_list(); }; break; } route[Term_Standalone] { log(1,">> Term_Standalone\n"); loose_route(); t_on_reply("Term_Standalone_reply"); #t_on_failure("Term_Standalone_failure"); if (!P_security_relay()) P_NAT_relay(); if (!t_relay()) { sl_send_reply("500","Error forwarding terminating standalone request"); break; }; } onreply_route[Term_Standalone_reply] { log(1,">> Term_Standalone_reply\n"); P_assert_called_identity(); if (!P_follows_via_list()) { log(1,">> P_follows_via_list - failed\n"); P_enforce_via_list(); }; break; } failure_route[Term_Standalone_failure] { log(1,">> Term_Standalone_failure\n"); if (!P_follows_via_list()) { log(1,">> P_follows_via_list - failed\n"); P_enforce_via_list(); }; break; }
1.5.2