Selaa lähdekoodia

CDP: Add config function to check availability of Diameter-Services (e.g. check, if Cx/Dx Interface is up)

Carsten Bock 8 vuotta sitten
vanhempi
commit
c9a73ec7e2

+ 69 - 0
src/modules/cdp/cdp_functions.c

@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2017 Carsten Bock, ng-voice GmbH ([email protected])
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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 "cdp_functions.h"
+#include "peermanager.h"
+#include "peerstatemachine.h"
+#include "receiver.h"
+#include "../../core/str.h"
+#include "../../core/dprint.h"
+
+extern dp_config *config;
+extern peer_list_t *peer_list;
+extern gen_lock_t *peer_list_lock;
+extern char *dp_states[];
+
+int check_peer(str * peer_fqdn) {
+	peer * p;
+	p = get_peer_by_fqdn(peer_fqdn);
+	if (p && !p->disabled &&  (p->state == I_Open || p->state == R_Open)) {
+		return 1;
+	} else {
+		return -1;
+	}	
+}
+
+int check_application(int vendorid, int application) 
+{
+	peer *i, *j;
+	int c;
+
+	lock_get(peer_list_lock);
+	i = peer_list->head;
+	while (i) {
+		lock_get(i->lock);
+		if (i && !i->disabled &&  (i->state == I_Open || i->state == R_Open)) {
+			for (c = 0; c < i->applications_cnt; c++) {
+				if (((vendorid <= 0) || (vendorid == i->applications[c].vendor)) && (i->applications[c].id == application)) {
+					lock_release(i->lock);
+					lock_release(peer_list_lock);
+					return 1;
+				}
+			}
+		}
+		j=i;
+		i = i->next;
+		lock_release(j->lock);
+	}
+	lock_release(peer_list_lock);
+	return -1;
+}
+

+ 32 - 0
src/modules/cdp/cdp_functions.h

@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2017 Carsten Bock, ng-voice GmbH ([email protected])
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * This file 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
+ *
+ *
+ * This file 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 CDP_FUNCTIONS_H_
+#define CDP_FUNCTIONS_H_
+
+#include "../../core/str.h"
+
+int check_peer(str *);
+int check_application(int, int);
+
+#endif /* CDP_FUNCTIONS_H_ */

+ 85 - 0
src/modules/cdp/cdp_mod.c

@@ -54,6 +54,8 @@
 #include "../../core/rpc_lookup.h"
 #include "../../core/cfg/cfg_struct.h"
 #include "cdp_stats.h"
+#include "cdp_functions.h"
+#include "../../core/mod_fix.h"
 
 MODULE_VERSION
 
@@ -66,6 +68,13 @@ unsigned int debug_heavy = 0;
 
 extern dp_config *config; 				/**< DiameterPeer configuration structure */
 
+static int w_cdp_check_peer(sip_msg_t *msg, char *peer, char *p2);
+static int w_cdp_has_app(sip_msg_t *msg, char *appid, char *param);
+static int w_cdp_has_app2(sip_msg_t *msg, char *vendor, char *appid);
+static int w_cdp_has_app(sip_msg_t *msg, char *appid, char *param);
+
+
+
 #define EXP_FUNC(NAME) \
 {#NAME, (cmd_function)NAME, NO_SCRIPT, 0, 0},
 /**
@@ -103,6 +112,12 @@ extern dp_config *config; 				/**< DiameterPeer configuration structure */
  * - AAAAddResponseHandler() - add a #AAAResponseHandler_f callback to responses being received
  */
 static cmd_export_t cdp_cmds[] = {
+	{"cdp_check_peer", (cmd_function)w_cdp_check_peer, 1, fixup_spve_null,
+		0, ANY_ROUTE},
+	{"cdp_has_app", (cmd_function)w_cdp_has_app, 1, fixup_igp_null,
+		0, ANY_ROUTE},
+	{"cdp_has_app", (cmd_function)w_cdp_has_app2, 2, fixup_igp_igp,
+		0, ANY_ROUTE},
 	{"load_cdp",					(cmd_function)load_cdp, 				NO_SCRIPT, 0, 0},
 
 	EXP_FUNC(AAACreateRequest)
@@ -244,3 +259,73 @@ static int cdp_exit( void )
 	LM_INFO("... CDiameterPeer child stopped\n");
 	return 0;
 }
+
+int w_cdp_check_peer(sip_msg_t *msg, char *peer, char *p2) {
+	str s;
+	if(fixup_get_svalue(msg, (gparam_p)peer, &s)<0)
+	{
+		LM_ERR("cannot get the peer\n");
+		return -1;
+	}
+	if (s.len > 0) {
+		return check_peer(&s);
+	}
+	return -1;
+}
+
+static int w_cdp_has_app(sip_msg_t *msg, char *appid, char *param) {
+	unsigned int app_flags;
+	str app_s = STR_NULL;
+	int a;
+	if(msg == NULL)
+		return -1;
+
+	if (get_is_fparam(&a, &app_s, msg, (fparam_t *)appid, &app_flags) != 0) {
+		LM_ERR("no Vendor-ID\n");
+		return -1;
+	}  
+	if(!(app_flags & PARAM_INT)) {
+		if(app_flags & PARAM_STR)
+			LM_ERR("unable to get app from [%.*s]\n", app_s.len,
+					app_s.s);
+		else
+			LM_ERR("unable to get app\n");
+		return -1;
+	}
+	return check_application(-1, a);
+}
+
+static int w_cdp_has_app2(sip_msg_t *msg, char *vendor, char *appid) {
+	unsigned int vendor_flags, app_flags;
+	str vendor_s = STR_NULL;
+	str app_s = STR_NULL;
+	int v, a;
+	if(msg == NULL)
+		return -1;
+
+	if (get_is_fparam(&v, &vendor_s, msg, (fparam_t *)vendor, &vendor_flags) != 0) {
+		LM_ERR("no Vendor-ID\n");
+		return -1;
+	} 
+	if(!(vendor_flags & PARAM_INT)) {
+		if(vendor_flags & PARAM_STR)
+			LM_ERR("unable to get vendor from [%.*s]\n", vendor_s.len,
+					vendor_s.s);
+		else
+			LM_ERR("unable to get vendor\n");
+		return -1;
+	}
+	if (get_is_fparam(&a, &app_s, msg, (fparam_t *)appid, &app_flags) != 0) {
+		LM_ERR("no Vendor-ID\n");
+		return -1;
+	}  
+	if(!(app_flags & PARAM_INT)) {
+		if(app_flags & PARAM_STR)
+			LM_ERR("unable to get app from [%.*s]\n", app_s.len,
+					app_s.s);
+		else
+			LM_ERR("unable to get app\n");
+		return -1;
+	}
+	return check_application(v, a);
+}

+ 13 - 1
src/modules/cdp/doc/cdp.xml

@@ -25,7 +25,7 @@
 		<firstname>Jason</firstname>
 		<surname>Penton</surname>
 		<address>
-			<email>[email protected]</email>
+			<email>[email protected]</email>q
 		</address>
 		</editor>
 		<editor>
@@ -35,6 +35,14 @@
 			<email>[email protected]</email>
 		</address>
 		</editor>
+		<editor>
+		<firstname>Carsten</firstname>
+		<surname>Bock</surname>
+		<affiliation><orgname>ng-voice GmbH</orgname></affiliation>
+		<address>
+			<email>[email protected]</email>
+		</address>
+		</editor>
 	</authorgroup>
 	<copyright>
 		<year>2006</year>
@@ -44,6 +52,10 @@
 		<year>2012</year>
 		<holder>Smile Communications</holder>
 	</copyright>
+	<copyright>
+		<year>2017</year>
+		<holder>ng-voice GmbH</holder>
+	</copyright>
 	</bookinfo>
 	<toc></toc>
 	

+ 76 - 0
src/modules/cdp/doc/cdp_admin.xml

@@ -165,6 +165,82 @@ modparam("cdp", "debug_heavy", 1)
  </section>
   </section>
 
+
+
+	<section>
+	<title>Functions</title>
+  	<section id="cdp.f.cdp_check_peer">
+ 		<title>
+ 		<function moreinfo="none">cdp_check_peer(fqdn)</function>
+ 		</title>
+ 		<para>
+ 		The method checks, if a specific peer is connected and ready.
+ 		</para>
+		<para>Meaning of the parameter is as follows:</para>
+		<itemizedlist>
+		<listitem>
+			<para>
+			<emphasis>fqdn</emphasis> - the Fully qualified domai
+				name of the peer, that should be checked.
+				The parameter may contain pseudovariables.
+			</para>
+		</listitem>
+		</itemizedlist>
+		<example>
+		<title><function>cdp_check_peer</function> usage</title>
+		<programlisting format="linespecific">
+...
+if(!cdp_check_peer("hss.mnc001.mcc001.3gppnetwork.org")) {
+	send_reply("503", "HSS not ready");
+	exit;
+}
+...
+</programlisting>
+		</example>
+	</section>
+  	<section id="cdp.f.cdp_has_app">
+ 		<title>
+ 		<function moreinfo="none">cdp_has_app([vendorid, ]application)</function>
+ 		</title>
+ 		<para>
+ 		The method checks, if any peer with this specific application has connected.
+ 		</para>
+		<para>Meaning of the parameters are as follows:</para>
+		<itemizedlist>
+		<listitem>
+			<para>
+			<emphasis>vendorid</emphasis> - The Vendor ID of the App
+			</para>
+			<para>
+			<emphasis>application</emphasis> - The Application ID
+			</para>
+		</listitem>
+		</itemizedlist>
+		<example>
+		<title><function>cdp_check_peer</function> usage</title>
+		<programlisting format="linespecific">
+...
+if(!cdp_has_app("10415", "4")) {
+	send_reply("503", "Charging Server not ready");
+	exit;
+}
+...
+</programlisting>
+		</example>
+		<example>
+		<title><function>cdp_check_peer</function> usage</title>
+		<programlisting format="linespecific">
+...
+if(!cdp_has_app("16777216")) {
+	send_reply("503", "Cx/Dx Interface not ready");
+	exit;
+}
+...
+</programlisting>
+		</example>
+	</section>
+	</section>
+
   <section>
     <title>RPC Commands</title>