2
0
Эх сурвалжийг харах

modules/ims_registrar_pcscf: new module function lookup_transport
- this allows terminating P-CSCF to check(and possibly) change the transport for the request before relaying/fwding to terminating UE

Jason Penton 11 жил өмнө
parent
commit
9f7fec41c0

+ 106 - 0
modules/ims_registrar_pcscf/lookup.c

@@ -0,0 +1,106 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
+ * The initial version of this code was written by Dragos Vingarzan
+ * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
+ * Fruanhofer Institute. It was and still is maintained in a separate
+ * branch of the original SER. We are therefore migrating it to
+ * Kamailio/SR and look forward to maintaining it from here on out.
+ * 2011/2012 Smile Communications, Pty. Ltd.
+ * ported/maintained/improved by 
+ * Jason Penton (jason(dot)penton(at)smilecoms.com and
+ * Richard Good (richard(dot)good(at)smilecoms.com) as part of an 
+ * effort to add full IMS support to Kamailio/SR using a new and
+ * improved architecture
+ * 
+ * NB: Alot of this code was originally part of OpenIMSCore,
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
+ * break apart the various CSCF functions into logically separate
+ * components. We hope this will drive wider use. We also feel
+ * that in this way the architecture is more complete and thereby easier
+ * to manage in the Kamailio/SR environment
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+
+#include <string.h>
+#include "reg_mod.h"
+#include "lookup.h"
+
+extern usrloc_api_t ul;
+
+/*! \brief
+ * Lookup contact in the database and rewrite Request-URI
+ * \return:  1 : contacts found and returned
+ *          -1 : not found
+ *          -2 : error
+ */
+int lookup_transport(struct sip_msg* _m, udomain_t* _d, str* _uri) {
+    str uri;
+    pcontact_t* pcontact;
+    char tmp[MAX_URI_SIZE];
+    str tmp_s;
+    int ret = 1;
+
+    if (_m->new_uri.s) uri = _m->new_uri;
+    else uri = _m->first_line.u.request.uri;
+
+    //now lookup in usrloc
+    ul.lock_udomain(_d, &uri);
+    if (ul.get_pcontact(_d, &uri, &pcontact) != 0) { //need to insert new contact
+	LM_WARN("received request for contact that we don't know about\n");
+	ret = -1;
+	goto done;
+    }
+    
+    if (pcontact->received_proto != _m->rcv.proto) {
+	reset_dst_uri(_m);
+	memset(tmp, 0, MAX_URI_SIZE);	
+	switch (pcontact->received_proto) {
+	    case PROTO_TCP:
+		snprintf(tmp, MAX_URI_SIZE, "%.*s;transport=tcp", pcontact->aor.len, pcontact->aor.s);
+		break;
+	    case PROTO_UDP:
+		snprintf(tmp, MAX_URI_SIZE, "%.*s;transport=udp", pcontact->aor.len, pcontact->aor.s);
+		break;
+	    default:
+		LM_WARN("unsupported transport [%d]\n", pcontact->received_proto);
+		ret = -2;
+		goto done;
+	}
+    }
+	
+    tmp_s.s = tmp;
+    tmp_s.len = strlen(tmp);
+    if (set_dst_uri(_m, &tmp_s) < 0) {
+	LM_ERR("failed to set dst_uri for terminating UE\n");
+	ret = -2;
+	goto done;
+    }
+    LM_DBG("Changed dst URI transport for UE to [%.*s]\n", tmp_s.len, tmp_s.s);
+    
+done:
+    ul.unlock_udomain(_d, &uri);
+    return ret;
+}
+

+ 59 - 0
modules/ims_registrar_pcscf/lookup.h

@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * Copyright (C) 2012 Smile Communications, [email protected]
+ * 
+ * The initial version of this code was written by Dragos Vingarzan
+ * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
+ * Fruanhofer Institute. It was and still is maintained in a separate
+ * branch of the original SER. We are therefore migrating it to
+ * Kamailio/SR and look forward to maintaining it from here on out.
+ * 2011/2012 Smile Communications, Pty. Ltd.
+ * ported/maintained/improved by 
+ * Jason Penton (jason(dot)penton(at)smilecoms.com and
+ * Richard Good (richard(dot)good(at)smilecoms.com) as part of an 
+ * effort to add full IMS support to Kamailio/SR using a new and
+ * improved architecture
+ * 
+ * NB: Alot of this code was originally part of OpenIMSCore,
+ * FhG Fokus. 
+ * Copyright (C) 2004-2006 FhG Fokus
+ * Thanks for great work! This is an effort to 
+ * break apart the various CSCF functions into logically separate
+ * components. We hope this will drive wider use. We also feel
+ * that in this way the architecture is more complete and thereby easier
+ * to manage in the Kamailio/SR environment
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ */
+
+#ifndef LOOKUP_H
+#define	LOOKUP_H
+
+#include "../../parser/msg_parser.h"
+#include "../../modules/ims_usrloc_pcscf/usrloc.h"
+
+
+/*! \brief
+ * Lookup a contact in ims_usrloc_pcscf and rewrite R-URI if found and received request transport is different to contact transport
+ */
+int lookup_transport(struct sip_msg* _m, udomain_t* _d, str* _uri);
+
+#endif	/* LOOKUP_H */
+

+ 28 - 13
modules/ims_registrar_pcscf/reg_mod.c

@@ -66,6 +66,7 @@
 #include "reg_mod.h"
 #include "save.h"
 #include "service_routes.h"
+#include "lookup.h"
 
 MODULE_VERSION
 
@@ -110,6 +111,8 @@ static int w_reginfo_handle_notify(struct sip_msg* _m, char* _d, char* _foo);
 static int w_assert_identity(struct sip_msg* _m, char* _d, char* _preferred_uri);
 static int w_assert_called_identity(struct sip_msg* _m, char* _d, char* _foo);
 
+static int w_lookup_transport(struct sip_msg* _m, char* _d, char* _uri);
+
 /*! \brief Fixup functions */
 static int domain_fixup(void** param, int param_no);
 static int save_fixup2(void** param, int param_no);
@@ -130,18 +133,15 @@ inline void pcscf_act_time()
  * Exported functions
  */
 static cmd_export_t cmds[] = {
-	{"pcscf_save",     		(cmd_function)w_save,       	1,  	save_fixup2, 	0,		ONREPLY_ROUTE },
-	{"pcscf_save_pending",	(cmd_function)w_save_pending,       	1,  	save_fixup2, 	0,		REQUEST_ROUTE },
-
-	{"pcscf_follows_service_routes", (cmd_function)w_follows_service_routes,       	1,  	save_fixup2, 	0,		REQUEST_ROUTE },
-	{"pcscf_force_service_routes", (cmd_function)w_force_service_routes,       	1,  	save_fixup2, 	0,		REQUEST_ROUTE },
-
-	{"pcscf_is_registered", (cmd_function)w_is_registered,       	1,  	save_fixup2, 	0,		REQUEST_ROUTE|ONREPLY_ROUTE },
-
-	{"pcscf_assert_identity", (cmd_function)w_assert_identity,      2,  	assert_identity_fixup, 	0,		REQUEST_ROUTE },
-	{"pcscf_assert_called_identity", (cmd_function)w_assert_called_identity,      1,  	assert_identity_fixup, 	0,		ONREPLY_ROUTE },
-
-	{"reginfo_handle_notify", (cmd_function)w_reginfo_handle_notify, 1, domain_fixup, 0, REQUEST_ROUTE},
+	{"pcscf_save",     		(cmd_function)w_save,                   1,  	save_fixup2,            0,		ONREPLY_ROUTE },
+	{"pcscf_save_pending",          (cmd_function)w_save_pending,       	1,  	save_fixup2,            0,		REQUEST_ROUTE },
+	{"pcscf_follows_service_routes",(cmd_function)w_follows_service_routes, 1,  	save_fixup2,            0,		REQUEST_ROUTE },
+	{"pcscf_force_service_routes",  (cmd_function)w_force_service_routes,   1,  	save_fixup2,            0,		REQUEST_ROUTE },
+	{"pcscf_is_registered",         (cmd_function)w_is_registered,          1,  	save_fixup2,            0,		REQUEST_ROUTE|ONREPLY_ROUTE },
+	{"pcscf_assert_identity",       (cmd_function)w_assert_identity,        2,  	assert_identity_fixup,  0,		REQUEST_ROUTE },
+	{"pcscf_assert_called_identity",(cmd_function)w_assert_called_identity, 1,  assert_identity_fixup,  0,		ONREPLY_ROUTE },
+	{"reginfo_handle_notify",       (cmd_function)w_reginfo_handle_notify,  1,      domain_fixup,           0,              REQUEST_ROUTE},
+        {"lookup_transport",		(cmd_function)w_lookup_transport,                 1,      domain_fixup,           0,              REQUEST_ROUTE|FAILURE_ROUTE},
 	
 	{0, 0, 0, 0, 0, 0}
 };
@@ -153,7 +153,7 @@ static cmd_export_t cmds[] = {
 static param_export_t params[] = {
 	{"pcscf_uri",                   PARAM_STR, &pcscf_uri                           },
 	{"pending_reg_expires",         INT_PARAM, &pending_reg_expires			},
-	{"received_avp",                STR_PARAM, &rcv_avp_param       		},
+	{"received_avp",                PARAM_STR, &rcv_avp_param       		},
 	{"is_registered_fallback2ip",	INT_PARAM, &is_registered_fallback2ip           },
 	{"publish_reginfo",             INT_PARAM, &publish_reginfo                     },
         {"subscribe_to_reginfo",        INT_PARAM, &subscribe_to_reginfo                },
@@ -373,6 +373,21 @@ static int w_save(struct sip_msg* _m, char* _d, char* _cflags)
 	return save(_m, (udomain_t*)_d, ((int)(unsigned long)_cflags));
 }
 
+/*! \brief
+ * Wrapper to lookup_transport(location)
+ */
+static int w_lookup_transport(struct sip_msg* _m, char* _d, char* _uri)
+{
+	str uri = {0};
+	if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
+	{
+		LM_ERR("invalid uri parameter\n");
+		return -1;
+	}
+
+	return lookup_transport(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL);
+}
+
 static int w_save_pending(struct sip_msg* _m, char* _d, char* _cflags)
 {
 	return save_pending(_m, (udomain_t*)_d);

+ 2 - 0
modules/ims_registrar_pcscf/reg_mod.h

@@ -54,6 +54,8 @@
 #include "../../modules/tm/tm_load.h"
 
 #define RECEIVED_MAX_SIZE      255
+#define USERNAME_MAX_SIZE      64
+#define DOMAIN_MAX_SIZE        128
 
 extern unsigned short rcv_avp_type;
 extern int_str rcv_avp_name;