Pārlūkot izejas kodu

Merge pull request #429 from smititelu/KAMAILIO-29

Rtpengine table changes
Richard Fuchs 9 gadi atpakaļ
vecāks
revīzija
5c7ee4576e

+ 12 - 0
lib/srdb1/schema/kamailio-rtpengine.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE database PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN"
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+  <!ENTITY % entities SYSTEM "entities.xml">
+  %entities;
+]>
+
+<database xmlns:xi="http://www.w3.org/2001/XInclude">
+    <name>RTPEngine</name>
+    <xi:include href="rtpengine.xml"/>
+</database>

+ 60 - 0
lib/srdb1/schema/rtpengine.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="rtpengine" xmlns:db="http://docbook.org/ns/docbook">
+    <name>rtpengine</name>
+    <version>1</version>
+    <type db="mysql">&MYSQL_TABLE_TYPE;</type>
+    <description>
+        <db:para>This table is used by the rtpengine module. It contains the sets of rtpengine instances used for proxying media between endpoints. More information about the rtpengine module can be found at: &KAMAILIO_MOD_DOC;rtpengine.html
+        </db:para>
+    </description>
+
+    <column id="setid">
+        <name>setid</name>
+        <type>unsigned int</type>
+	<size>10</size>
+        <description>RTPEngine instance set ID</description>
+        <default>0</default>
+        <natural/>
+    </column>
+
+    <column id="url">
+        <name>url</name>
+        <type>string</type>
+        <size>64</size>
+        <description>RTPEngine instance socket URL</description>
+    </column>
+
+    <column id="weight">
+        <name>weight</name>
+        <type>unsigned int</type>
+	<size>10</size>
+        <description>RTPEngine instance weight</description>
+        <default>1</default>
+        <natural/>
+    </column>
+
+    <column id="disabled">
+        <name>disabled</name>
+        <type>int</type>
+	<size>1</size>
+        <description>RTPEngine instance state</description>
+        <default>0</default>
+        <natural/>
+    </column>
+
+    <index>
+        <name>rtpengine_nodes</name>
+        <colref linkend="setid"/>
+        <colref linkend="url"/>
+        <primary/>
+    </index>
+
+</table>

+ 216 - 1
modules/rtpengine/doc/rtpengine_admin.xml

@@ -221,6 +221,11 @@ modparam("rtpengine", "rtpengine_tout_ms", 2000)
 		This is <emphasis>useful</emphasis> when deactivating a node for maintanance and reject new sessions but allow current ones to finish.
 		</para>
 		<para>
+		The behaviour is the same for a rtpengine deleted table node.
+		When the node is deleted from the table and the table reloaded (see nh_reload_rtpp) the node actually is disabled(permanent) and hidden for display.
+		Next time the same node will be added in the table, and the content reloaded, it will be updated and re-displayed.
+		</para>
+		<para>
 		<emphasis>
 		Default value is <quote>0</quote> to keep the current behaviour.
 		</emphasis>
@@ -294,7 +299,7 @@ modparam("rtpengine", "extra_id_pv", "$avp(extra_id)")
 		</example>
 	</section>
 
-	<section id="rtpengine.p.setid_pv">
+	<section id="rtpengine.p.setid_avp">
 		<title><varname>setid_avp</varname> (string)</title>
 		<para>
 			The parameter defines an AVP that, if set,
@@ -453,13 +458,199 @@ modparam("rtpengine", "hash_table_size", "123")
 ...
 modparam("rtpengine", "hash_table_tout", "300")
 ...
+</programlisting>
+                </example>
+        </section>
+
+
+
+
+	<section id="rtpengine.p.db_url">
+		<title><varname>db_url</varname> (string)</title>
+		<para>
+			The rtpengine datablase url. If present and valid, it activates database mode.
+			Node information is read from database, not from config.
+		</para>
+		<para>
+			By default, the datablase url is NULL (not set).
+		</para>
+		<example>
+		<title>Set <varname>db_url</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "db_url", "mysql://pass@localhost/db")
+...
+</programlisting>
+		</example>
+	</section>
+
+
+	<section id="rtpengine.p.table_name">
+		<title><varname>table_name</varname> (string)</title>
+		<para>
+			The rtpengine table name. If database mode is activated (i.e. valid db_url),
+			set the name of rtpengine table, on startup.
+		</para>
+		<para>
+			By default, the rtpengine table name is "rtpengine".
+		</para>
+		<para>
+			NOTE: One needs to add the version of the rtpengine table in the version table.
+			The current version is version 1.
+		</para>
+		<example>
+		<title>Set <varname>table_name</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "table_name", "rtpengine_table_name")
+...
+</programlisting>
+		</example>
+
+		<example>
+		<title>Setup <varname>rtpengine</varname> table</title>
+<programlisting format="linespecific">
+mysql> describe rtpengine;
++----------+------------------+------+-----+---------+-------+
+| Field    | Type             | Null | Key | Default | Extra |
++----------+------------------+------+-----+---------+-------+
+| setid    | int(10) unsigned | NO   |     | NULL    |       |
+| url      | varchar(256)     | NO   |     | NULL    |       |
+| weight   | int(10) unsigned | NO   |     | NULL    |       |
+| disabled | int(11)          | NO   |     | NULL    |       |
++----------+------------------+------+-----+---------+-------+
+
+mysql> select * from rtpengine;
++-------+---------------------------+--------+----------+
+| setid | url                       | weight | disabled |
++-------+---------------------------+--------+----------+
+|     0 | udp:rtpproxy1.domain:8800 |    100 |        0 |
+|     0 | udp:rtpproxy2.domain:8800 |    200 |        1 |
++-------+---------------------------+--------+----------+
+
+mysql> select * from version;
++---------------------------+---------------+
+| table_name                | table_version |
++---------------------------+---------------+
+| rtpengine                 |             1 |
++---------------------------+---------------+
 </programlisting>
 		</example>
 	</section>
 
 
+	<section id="rtpengine.p.setid_col">
+		<title><varname>setid_col</varname> (string)</title>
+		<para>
+			Column name in the rtpengine table. If database mode is activated (i.e. valid db_url),
+			set the setid of rtp nodes according to this column, on startup.
+			The MySQL value for this column should be INT UNSIGNED.
+		</para>
+		<para>
+			By default, the column name is "setid".
+		</para>
+		<example>
+		<title>Set <varname>setid_col</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "setid_col", "setid_column_name")
+...
+</programlisting>
+		</example>
+	</section>
+
+
+	<section id="rtpengine.p.url_col">
+		<title><varname>url_col</varname> (string)</title>
+		<para>
+			Column name in the rtpengine table. If database mode is activated (i.e. valid db_url),
+			set the url of rtp nodes according to this column, on startup.
+			The MySQL value for this column should be VARCHAR.
+		</para>
+		<para>
+			By default, the column name is "url".
+		</para>
+		<example>
+		<title>Set <varname>url_col</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "url_col", "url_column_name")
+...
+</programlisting>
+		</example>
 	</section>
 
+
+	<section id="rtpengine.p.weight_col">
+		<title><varname>weight_col</varname> (string)</title>
+		<para>
+			Column name in the rtpengine table. If database mode is activated (i.e. valid db_url),
+			set the weight of rtp nodes according to this column, on startup. The column value has
+			priority over the URL weight.
+			The MySQL value for this column should be INT UNSIGNED.
+		</para>
+		<para>
+			By default, the column name is "weight".
+		</para>
+		<example>
+		<title>Set <varname>weight_col</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "weight_col", "weight_column_name")
+...
+</programlisting>
+		</example>
+	</section>
+
+
+	<section id="rtpengine.p.disabled_col">
+		<title><varname>disabled_col</varname> (string)</title>
+		<para>
+			Column name in the rtpengine table. If database mode is activated (i.e. valid db_url),
+			set the state of rtp nodes according to this column, on startup.
+			The MySQL value for this column should be INT.
+		</para>
+		<para>
+			By default, the column name is "disabled".
+		</para>
+		<example>
+		<title>Set <varname>disabled_col</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "disabled_col", "disabled_column_name")
+...
+</programlisting>
+		</example>
+	</section>
+
+
+	<section id="rtpengine.p.setid_default">
+		<title><varname>setid_default</varname> (string)</title>
+		<para>
+			The default set of nodes to be used.
+		</para>
+		<para>
+			By default, the setid is 0.
+		</para>
+		<para>
+			NOTE that if setid_avp is configured, this value will be ignored and
+			the active set will be chosen according to the setid_avp.
+		</para>
+		<example>
+		<title>Set <varname>setid_default</varname> parameter</title>
+<programlisting format="linespecific">
+...
+modparam("rtpengine", "setid_default", 11)
+...
+</programlisting>
+		</example>
+	</section>
+
+	</section>
+
+
+
+
 	<section>
 	<title>Functions</title>
 	<section id="rtpengine.f.set_rtpengine_set">
@@ -1067,6 +1258,30 @@ $ &ctltool; fifo nh_ping_rtpp all
 			</example>
 		</section>
 
+
+	    <section id="rtpengine.m.nh_reload_rtpp">
+			<title><function moreinfo="none">nh_reload_rtpp</function></title>
+			<para>
+				Reloads the database node table content <emphasis>if configured</emphasis>.
+				Returns specific message related to success, failure and no db_url configured.
+			</para>
+			<para>
+				NOTE: The current behaviour updates the nodes state or creates new ones or
+				hides old ones, based on the database content. If allow_op modparam is enabled,
+				the sessions are still allowed to finish for the hidden old nodes.
+			</para>
+			<example>
+			<title>
+				<function moreinfo="none">nh_reload_rtpp</function> usage</title>
+			<programlisting format="linespecific">
+...
+$ &ctltool; fifo nh_reload_rtpp
+...
+			</programlisting>
+			</example>
+		</section>
+
+
 	    <section id="rtpengine.m.nh_show_hash_total">
 			<title><function moreinfo="none">nh_show_hash_total</function></title>
 			<para>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 439 - 263
modules/rtpengine/rtpengine.c


+ 27 - 13
modules/rtpengine/rtpengine.h

@@ -26,47 +26,61 @@
 #include "bencode.h"
 #include "../../str.h"
 
+#define MI_MIN_RECHECK_TICKS		0
+#define MI_MAX_RECHECK_TICKS		((unsigned int)-1)
+
 struct rtpp_node {
 	unsigned int		idx;			/* overall index */
-	str					rn_url;			/* unparsed, deletable */
-	int					rn_umode;
-	char				*rn_address;	/* substring of rn_url */
-	int					rn_disabled;	/* found unaccessible? */
-	unsigned			rn_weight;		/* for load balancing */
+	str			rn_url;			/* unparsed, deletable */
+	int			rn_umode;
+	char			*rn_address;		/* substring of rn_url */
+	int			rn_disabled;		/* found unaccessible? */
+	unsigned int		rn_weight;		/* for load balancing */
+	unsigned int		rn_displayed;		/* for delete at db reload */
 	unsigned int		rn_recheck_ticks;
-        int                     rn_rep_supported;
-        int                     rn_ptl_supported;
+	int			rn_rep_supported;
+	int			rn_ptl_supported;
 	struct rtpp_node	*rn_next;
 };
 
 
-struct rtpp_set{
+struct rtpp_set {
 	unsigned int 		id_set;
-	unsigned			weight_sum;
+	unsigned int		weight_sum;
 	unsigned int		rtpp_node_count;
-	int 				set_disabled;
+	int 			set_disabled;
 	unsigned int		set_recheck_ticks;
 	struct rtpp_node	*rn_first;
 	struct rtpp_node	*rn_last;
-	struct rtpp_set     *rset_next;
+	struct rtpp_set	 	*rset_next;
+	gen_lock_t		*rset_lock;
 };
 
 
-struct rtpp_set_head{
+struct rtpp_set_head {
 	struct rtpp_set		*rset_first;
 	struct rtpp_set		*rset_last;
+	gen_lock_t		*rset_head_lock;
 };
 
 
+struct rtpp_node *get_rtpp_node(struct rtpp_set *rtpp_list, str *url);
 struct rtpp_set *get_rtpp_set(int set_id);
-int add_rtpengine_socks(struct rtpp_set * rtpp_list, char * rtpproxy);
+int add_rtpengine_socks(struct rtpp_set * rtpp_list, char * rtpproxy, unsigned int weight, int disabled, unsigned int ticks, int isDB);
+
+int rtpengine_delete_node(struct rtpp_node *rtpp_node);
+int rtpengine_delete_node_set(struct rtpp_set *rtpp_list);
+int rtpengine_delete_node_all();
 
 
 int init_rtpproxy_db(void);
 
 extern str rtpp_db_url;
 extern str rtpp_table_name;
+extern str rtpp_setid_col;
 extern str rtpp_url_col;
+extern str rtpp_weight_col;
+extern str rtpp_disabled_col;
 
 
 #endif

+ 25 - 10
modules/rtpengine/rtpengine_db.c

@@ -31,9 +31,11 @@ static db_func_t rtpp_dbf;
 static db1_con_t *rtpp_db_handle = NULL;
 
 str rtpp_db_url = {NULL, 0};
-str rtpp_table_name = str_init("rtpproxy");
-str rtpp_set_id_col = str_init("set_id");
+str rtpp_table_name = str_init("rtpengine");
+str rtpp_setid_col = str_init("setid");
 str rtpp_url_col = str_init("url");
+str rtpp_weight_col = str_init("weight");
+str rtpp_disabled_col = str_init("disabled");
 
 static int rtpp_connect_db(void)
 {
@@ -63,13 +65,15 @@ static int rtpp_load_db(void)
 	db1_res_t *res = NULL;
 	db_val_t *values = NULL;
 	db_row_t *rows = NULL;
-	db_key_t query_cols[] = {&rtpp_set_id_col, &rtpp_url_col};
+	db_key_t query_cols[] = {&rtpp_setid_col, &rtpp_url_col, &rtpp_weight_col, &rtpp_disabled_col};
 
 	str url;
-	int set_id;
+	int setid, disabled;
+	unsigned int weight, ticks;
+
 	/* int weight, flags; */
 	int n_rows = 0;
-	int n_cols = 2;
+	int n_cols = 4;
 
 	if (rtpp_db_handle == NULL)
 	{
@@ -87,6 +91,8 @@ static int rtpp_load_db(void)
 		return -1;
 	}
 
+	rtpengine_delete_node_all();
+
 	n_rows = RES_ROW_N(res);
 	rows = RES_ROWS(res);
 	if (n_rows == 0)
@@ -94,26 +100,35 @@ static int rtpp_load_db(void)
 		LM_WARN("No rtpproxy instances in database\n");
 		return 0;
 	}
+
 	for (i=0; i<n_rows; i++)
 	{
 		values = ROW_VALUES(rows + i);
 
-		set_id = VAL_INT(values);
+		setid = VAL_INT(values);
 		url.s = VAL_STR(values+1).s;
 		url.len = strlen(url.s);
+		weight = VAL_INT(values+2);
+		disabled = VAL_INT(values+3);
+		if (disabled) {
+			ticks = MI_MAX_RECHECK_TICKS;
+		} else {
+			ticks = 0;
+		}
 		/*
 		weight = VAL_INT(values+2);
 		flags = VAL_INT(values+3);
 		*/
-		if ((rtpp_list = get_rtpp_set(set_id)) == NULL)
+		if ((rtpp_list = get_rtpp_set(setid)) == NULL)
 		{
-			LM_ERR("error getting rtpp_list for set %d\n", set_id);
+			LM_ERR("error getting rtpp_list for set %d\n", setid);
 			continue;
 		}
 
-		if (add_rtpengine_socks(rtpp_list, url.s) !=  0)
+		if (add_rtpengine_socks(rtpp_list, url.s, weight, disabled, ticks, 1) !=  0)
 		{
-			LM_ERR("error inserting '%.*s' into set %d\n", url.len, url.s, set_id);
+			LM_ERR("error inserting '%.*s' into set %d disabled=%d\n",
+				url.len, url.s, setid, disabled);
 		}
 	}
 

+ 10 - 0
utils/kamctl/db_berkeley/kamailio/rtpengine

@@ -0,0 +1,10 @@
+METADATA_COLUMNS
+setid(int) url(str) weight(int) disabled(int)
+METADATA_KEY
+0 2 3
+METADATA_READONLY
+0
+METADATA_LOGFLAGS
+0
+METADATA_DEFAULTS
+0|NIL|1|0

+ 2 - 0
utils/kamctl/db_berkeley/kamailio/version

@@ -102,6 +102,8 @@ rls_presentity|
 rls_presentity|1
 rls_watchers|
 rls_watchers|3
+rtpengine|
+rtpengine|1
 rtpproxy|
 rtpproxy|1
 sca_subscriptions|

+ 9 - 0
utils/kamctl/db_sqlite/rtpengine-create.sql

@@ -0,0 +1,9 @@
+INSERT INTO version (table_name, table_version) values ('rtpengine','1');
+CREATE TABLE rtpengine (
+    setid INTEGER DEFAULT 0 NOT NULL,
+    url VARCHAR(64) NOT NULL,
+    weight INTEGER DEFAULT 1 NOT NULL,
+    disabled INTEGER DEFAULT 0 NOT NULL,
+    CONSTRAINT rtpengine_rtpengine_nodes PRIMARY KEY  (setid, url)
+);
+

+ 1 - 0
utils/kamctl/dbtext/kamailio/rtpengine

@@ -0,0 +1 @@
+setid(int) url(string) weight(int) disabled(int) 

+ 1 - 0
utils/kamctl/dbtext/kamailio/version

@@ -46,6 +46,7 @@ purplemap:1
 re_grp:1
 rls_presentity:1
 rls_watchers:3
+rtpengine:1
 rtpproxy:1
 sca_subscriptions:1
 silo:8

+ 9 - 0
utils/kamctl/mysql/rtpengine-create.sql

@@ -0,0 +1,9 @@
+INSERT INTO version (table_name, table_version) values ('rtpengine','1');
+CREATE TABLE `rtpengine` (
+    `setid` INT(10) UNSIGNED DEFAULT 0 NOT NULL,
+    `url` VARCHAR(64) NOT NULL,
+    `weight` INT(10) UNSIGNED DEFAULT 1 NOT NULL,
+    `disabled` INT(1) DEFAULT 0 NOT NULL,
+    CONSTRAINT rtpengine_nodes PRIMARY KEY  (`setid`, `url`)
+);
+

+ 17 - 0
utils/kamctl/oracle/rtpengine-create.sql

@@ -0,0 +1,17 @@
+INSERT INTO version (table_name, table_version) values ('rtpengine','1');
+CREATE TABLE rtpengine (
+    setid NUMBER(10) DEFAULT 0 NOT NULL,
+    url VARCHAR2(64),
+    weight NUMBER(10) DEFAULT 1 NOT NULL,
+    disabled NUMBER(10) DEFAULT 0 NOT NULL,
+    CONSTRAINT rtpengine_rtpengine_nodes  PRIMARY KEY  (setid, url)
+);
+
+CREATE OR REPLACE TRIGGER rtpengine_tr
+before insert on rtpengine FOR EACH ROW
+BEGIN
+  auto_id(:NEW.id);
+END rtpengine_tr;
+/
+BEGIN map2users('rtpengine'); END;
+/

+ 9 - 0
utils/kamctl/postgres/rtpengine-create.sql

@@ -0,0 +1,9 @@
+INSERT INTO version (table_name, table_version) values ('rtpengine','1');
+CREATE TABLE rtpengine (
+    setid INTEGER DEFAULT 0 NOT NULL,
+    url VARCHAR(64) NOT NULL,
+    weight INTEGER DEFAULT 1 NOT NULL,
+    disabled INTEGER DEFAULT 0 NOT NULL,
+    CONSTRAINT rtpengine_rtpengine_nodes PRIMARY KEY  (setid, url)
+);
+

+ 32 - 0
utils/kamctl/xhttp_pi/pi_framework.xml

@@ -669,6 +669,15 @@
 		<column><field>from_domain</field><type>DB1_STR</type></column>
 		<column><field>updated</field><type>DB1_INT</type></column>
 	</db_table>
+	<!-- Declaration of rtpengine table-->
+	<db_table id="rtpengine">
+		<table_name>rtpengine</table_name>
+		<db_url_id>mysql</db_url_id>
+		<column><field>setid</field><type>DB1_INT</type></column>
+		<column><field>url</field><type>DB1_STR</type></column>
+		<column><field>weight</field><type>DB1_INT</type></column>
+		<column><field>disabled</field><type>DB1_INT</type></column>
+	</db_table>
 	<!-- Declaration of rtpproxy table-->
 	<db_table id="rtpproxy">
 		<table_name>rtpproxy</table_name>
@@ -3533,6 +3542,29 @@
 			</clause_cols>
 		</cmd>
 	</mod>
+	<!-- rtpengine provisionning -->
+	<mod><mod_name>rtpengine</mod_name>
+		<cmd><cmd_name>show</cmd_name>
+			<db_table_id>rtpengine</db_table_id>
+			<cmd_type>DB1_QUERY</cmd_type>
+			<query_cols>
+				<col><field>setid</field></col>
+				<col><field>url</field></col>
+				<col><field>weight</field></col>
+				<col><field>disabled</field></col>
+			</query_cols>
+		</cmd>
+		<cmd><cmd_name>add</cmd_name>
+			<db_table_id>rtpengine</db_table_id>
+			<cmd_type>DB1_INSERT</cmd_type>
+			<query_cols>
+				<col><field>setid</field></col>
+				<col><field>url</field></col>
+				<col><field>weight</field></col>
+				<col><field>disabled</field></col>
+			</query_cols>
+		</cmd>
+	</mod>
 	<!-- rtpproxy provisionning -->
 	<mod><mod_name>rtpproxy</mod_name>
 		<cmd><cmd_name>show</cmd_name>

+ 23 - 0
utils/kamctl/xhttp_pi/rtpengine-mod

@@ -0,0 +1,23 @@
+	<!-- rtpengine provisionning -->
+	<mod><mod_name>rtpengine</mod_name>
+		<cmd><cmd_name>show</cmd_name>
+			<db_table_id>rtpengine</db_table_id>
+			<cmd_type>DB1_QUERY</cmd_type>
+			<query_cols>
+				<col><field>setid</field></col>
+				<col><field>url</field></col>
+				<col><field>weight</field></col>
+				<col><field>disabled</field></col>
+			</query_cols>
+		</cmd>
+		<cmd><cmd_name>add</cmd_name>
+			<db_table_id>rtpengine</db_table_id>
+			<cmd_type>DB1_INSERT</cmd_type>
+			<query_cols>
+				<col><field>setid</field></col>
+				<col><field>url</field></col>
+				<col><field>weight</field></col>
+				<col><field>disabled</field></col>
+			</query_cols>
+		</cmd>
+	</mod>

+ 9 - 0
utils/kamctl/xhttp_pi/rtpengine-table

@@ -0,0 +1,9 @@
+	<!-- Declaration of rtpengine table-->
+	<db_table id="rtpengine">
+		<table_name>rtpengine</table_name>
+		<db_url_id>mysql</db_url_id>
+		<column><field>setid</field><type>DB1_INT</type></column>
+		<column><field>url</field><type>DB1_STR</type></column>
+		<column><field>weight</field><type>DB1_INT</type></column>
+		<column><field>disabled</field><type>DB1_INT</type></column>
+	</db_table>

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels