Преглед на файлове

ims_registrar_pcscf: update contacts with user callbacks

- save pending: save temp security params only for the pending contacts.
- update contacts: register user callback for successfuly registered
  contact to destroy the tunnels after contact deregistration or expiration.
Aleksandar Yosifov преди 6 години
родител
ревизия
7e46cdac98
променени са 2 файла, в които са добавени 44 реда и са изтрити 13 реда
  1. 15 0
      src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.c
  2. 29 13
      src/modules/ims_registrar_pcscf/save.c

+ 15 - 0
src/modules/ims_registrar_pcscf/ims_registrar_pcscf_mod.c

@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2012 Smile Communications, [email protected]
  * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2019 Aleksandar Yosifov
  *
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
@@ -57,6 +58,7 @@
 #include "../../modules/sl/sl.h"
 #include "../../core/mod_fix.h"
 #include "../../core/cfg/cfg_struct.h"
+#include "../ims_ipsec_pcscf/cmd.h"
 
 /* Bindings to PUA */
 #include "../pua/pua_bind.h"
@@ -73,6 +75,7 @@ usrloc_api_t ul;						/**!< Structure containing pointers to usrloc functions*/
 sl_api_t slb;							/**!< SL API structure */
 struct tm_binds tmb;					/**!< TM API structure */
 pua_api_t pua; 							/**!< PUA API structure */
+ipsec_pcscf_api_t ipsec_pcscf;			/**!< Structure containing pointers to ipsec pcscf functions*/
 
 int publish_reginfo = 0;
 int subscribe_to_reginfo = 0;
@@ -228,6 +231,7 @@ int fix_parameters() {
 static int mod_init(void) {
 	bind_usrloc_t bind_usrloc;
 	bind_pua_t bind_pua;
+	bind_ipsec_pcscf_t bind_ipsec_pcscf;
 
 	/*register space for event processor*/
 	register_procs(1);
@@ -259,6 +263,17 @@ static int mod_init(void) {
 	}
 	LM_DBG("Successfully bound to PCSCF Usrloc module\n");
 
+	bind_ipsec_pcscf = (bind_ipsec_pcscf_t) find_export("bind_ims_ipsec_pcscf", 1, 0);
+	if (!bind_ipsec_pcscf) {
+		LM_ERR("can't bind ims_ipsec_pcscf\n");
+		return -1;
+	}
+
+	if (bind_ipsec_pcscf(&ipsec_pcscf) < 0) {
+		return -1;
+	}
+	LM_INFO("Successfully bound to PCSCF IPSEC module\n");
+
        if(subscribe_to_reginfo == 1){
                /* Bind to PUA: */
                bind_pua = (bind_pua_t) find_export("bind_pua", 1, 0);

+ 29 - 13
src/modules/ims_registrar_pcscf/save.c

@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2012 Smile Communications, [email protected]
  * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2019 Aleksandar Yosifov
  * 
  * The initial version of this code was written by Dragos Vingarzan
  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
@@ -50,6 +51,7 @@
 #include "subscribe.h"
 
 #include "../pua/pua_bind.h"
+#include "../ims_ipsec_pcscf/cmd.h"
 #include "sec_agree.h"
 
 extern struct tm_binds tmb;
@@ -59,6 +61,7 @@ extern unsigned int pending_reg_expires;
 extern int subscribe_to_reginfo;
 extern int subscription_expires;
 extern pua_api_t pua;
+extern ipsec_pcscf_api_t ipsec_pcscf;
 
 struct sip_msg* get_request_from_reply(struct sip_msg* reply)
 {
@@ -228,7 +231,17 @@ static inline int update_contacts(struct sip_msg *req,struct sip_msg *rpl, udoma
 								expires-local_time_now);
 						ci.reg_state = PCONTACT_REGISTERED;
 						if (ul.update_pcontact(_d, &ci, pcontact) != 0) {
-							LM_ERR("failed to update pcscf contact\n");
+							LM_DBG("failed to update pcscf contact\n");
+						}else{
+							// Register callback to destroy related tunnels to this contact.
+							// The registration should be exact here, after the successfuly registration of the UE
+							LM_DBG("ul.register_ulcb(pcontact, PCSCF_CONTACT_EXPIRE|PCSCF_CONTACT_DELETE...)\n");
+							if(ul.register_ulcb(pcontact, PCSCF_CONTACT_EXPIRE|PCSCF_CONTACT_DELETE, ipsec_pcscf.ipsec_on_expire, NULL) != 1){
+								LM_DBG("Error subscribing for contact\n");
+							}
+
+							// After successful registration try to unregister all callbacks for pending contacts ralated to this contact.
+							ul.unreg_pending_contacts_cb(_d, pcontact, PCSCF_CONTACT_EXPIRE);
 						}
 						pcontact->expires = expires;
 					}
@@ -337,21 +350,25 @@ int save_pending(struct sip_msg* _m, udomain_t* _d) {
     // Parse security parameters
     security_t* sec_params = NULL;
     if((sec_params = cscf_get_security(_m)) == NULL) {
-        LM_ERR("Will save pending contact without security parameters\n");
+        LM_DBG("Will save pending contact without security parameters\n");
     }
 
 	// Parse security-verify parameters
     security_t* sec_verify_params = NULL;
     if((sec_verify_params = cscf_get_security_verify(_m)) == NULL){
-        LM_ERR("Will save pending contact without security-verify parameters\n");
+        LM_DBG("Will save pending contact without security-verify parameters\n");
     }else{
 		if(sec_params){
 			// for REGISTER request try to set spi pc and spi ps from security-verify header
 			sec_params->data.ipsec->spi_ps = sec_verify_params->data.ipsec->spi_us;
 			sec_params->data.ipsec->spi_pc = sec_verify_params->data.ipsec->spi_uc;
 
-			LM_DBG("Will save pending contact with security-verify parameters, spc_ps %u, spi_pc %u\n",
-					sec_params->data.ipsec->spi_ps, sec_params->data.ipsec->spi_pc);
+			// Get from verify header pcscf server and client ports
+			sec_params->data.ipsec->port_ps = sec_verify_params->data.ipsec->port_us;
+			sec_params->data.ipsec->port_pc = sec_verify_params->data.ipsec->port_uc;
+
+			LM_DBG("Will save pending contact with security-verify parameters, spc_ps %u, spi_pc %u, port_ps %u, port_pc %u\n",
+					sec_params->data.ipsec->spi_ps, sec_params->data.ipsec->spi_pc, sec_params->data.ipsec->port_ps, sec_params->data.ipsec->port_pc);
 		}
 	}
 
@@ -364,19 +381,18 @@ int save_pending(struct sip_msg* _m, udomain_t* _d) {
 		} else {
 			LM_DBG("registering for UL callback\n");
 			ul.register_ulcb(pcontact, PCSCF_CONTACT_DELETE | PCSCF_CONTACT_EXPIRE | PCSCF_CONTACT_UPDATE, callback_pcscf_contact_cb, NULL);
+
+			// Update security parameters only for the pending contacts
+			if(sec_params){
+				if(ul.update_temp_security(_d, sec_params->type, sec_params, pcontact) != 0){
+					LM_ERR("Error updating temp security\n");
+				}
+			}
 		}
 	} else { //contact already exists - update
         LM_DBG("Contact already exists - not doing anything for now\n");
 	}
 
-    // Update security parameters
-    if(sec_params) {
-        if(ul.update_temp_security(_d, sec_params->type, sec_params, pcontact) != 0)
-        {
-            LM_ERR("Error updating temp security\n");
-        }
-    }
-
 	ul.unlock_udomain(_d, &ci.via_host, ci.via_port, ci.via_prot);