[sr-dev] git:alexh/dialog-sync-wip: dialog: Introduce increment and offset for hash id's

Alex Hermann alex at speakup.nl
Thu Sep 4 13:21:34 CEST 2014


Module: sip-router
Branch: alexh/dialog-sync-wip
Commit: 7c717e04fa815556e102e92f03721a90d8800f17
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7c717e04fa815556e102e92f03721a90d8800f17

Author: Alex Hermann <alex at speakup.nl>
Committer: Alex Hermann <alex at speakup.nl>
Date:   Mon Aug 11 17:03:31 2014 +0200

dialog: Introduce increment and offset for hash id's

When replicating dialogs via dmq, the id's must not overlap. introduce an
offset and increment so each kamailio instance creates unique id's. The
increment must be identical between all involved proxies, the offset must
be unique.

---

 modules/dialog/dialog.c             |   14 +++++++++++
 modules/dialog/dlg_db_handler.c     |    8 ++----
 modules/dialog/dlg_hash.c           |   30 +++++++++++++++++++++--
 modules/dialog/dlg_hash.h           |    5 ++++
 modules/dialog/doc/dialog_admin.xml |   45 +++++++++++++++++++++++++++++++++++
 5 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/modules/dialog/dialog.c b/modules/dialog/dialog.c
index 83a17c6..b5b6321 100644
--- a/modules/dialog/dialog.c
+++ b/modules/dialog/dialog.c
@@ -112,6 +112,8 @@ int initial_cbs_inscript = 1;
 int dlg_wait_ack = 1;
 static int dlg_timer_procs = 0;
 int dlg_enable_dmq = 0;
+int dlg_id_offset = 1;
+int dlg_id_increment = 1;
 
 int dlg_event_rt[DLG_EVENTRT_MAX];
 
@@ -297,6 +299,8 @@ static param_export_t mod_params[]={
 	{ "timeout_noreset",       INT_PARAM, &dlg_timeout_noreset      },
 	{ "timer_procs",           PARAM_INT, &dlg_timer_procs          },
 	{ "enable_dmq",            INT_PARAM, &dlg_enable_dmq           },
+	{ "id_offset",             INT_PARAM, &dlg_id_offset            },
+	{ "id_increment",          INT_PARAM, &dlg_id_increment         },
 	{ 0,0,0 }
 };
 
@@ -516,6 +520,16 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (dlg_id_increment < 1) {
+		LM_ERR("invalid value for id_increment\n");
+		return -1;
+	}
+
+	if (dlg_id_offset < 1 || dlg_id_offset > dlg_id_increment) {
+		LM_ERR("invalid value for id_offset\n");
+		return -1;
+	}
+
 	if (timeout_spec.s) {
 		if ( pv_parse_spec(&timeout_spec, &timeout_avp)==0 
 				&& (timeout_avp.type!=PVT_AVP)){
diff --git a/modules/dialog/dlg_db_handler.c b/modules/dialog/dlg_db_handler.c
index a00f5ec..fcc04e8 100644
--- a/modules/dialog/dlg_db_handler.c
+++ b/modules/dialog/dlg_db_handler.c
@@ -304,7 +304,6 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 	str cseq1, cseq2, contact1, contact2, rroute1, rroute2;
 	str toroute_name;
 	str xdata;
-	unsigned int next_id;
 	srjson_doc_t jdoc;
 	
 	res = 0;
@@ -363,10 +362,9 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 			link_dlg(dlg, 0, 0);
 
 			dlg->h_id = VAL_INT(values+1);
-			next_id = d_table->entries[dlg->h_entry].next_id;
-
-			d_table->entries[dlg->h_entry].next_id =
-				(next_id < dlg->h_id) ? (dlg->h_id+1) : next_id;
+			if (dlg->h_id >= d_table->entries[dlg->h_entry].next_id) {
+				d_table->entries[dlg->h_entry].next_id = dlg_next_id(dlg->h_id);
+			}
 
 			GET_STR_VALUE(to_tag, values, 6, 1, 1);
 
diff --git a/modules/dialog/dlg_hash.c b/modules/dialog/dlg_hash.c
index 2a7b055..169bef6 100644
--- a/modules/dialog/dlg_hash.c
+++ b/modules/dialog/dlg_hash.c
@@ -69,6 +69,8 @@
 
 extern int dlg_ka_interval;
 extern int dlg_enable_dmq;
+extern int dlg_id_offset;
+extern int dlg_id_increment;
 
 /*! global dialog table */
 struct dlg_table *d_table = 0;
@@ -265,6 +267,27 @@ int dlg_clean_run(ticks_t ti)
 }
 
 /*!
+ * \brief Create next id based on offset and increment
+ * \param id current value
+ */
+unsigned int inline dlg_next_id(unsigned int id)
+{
+	unsigned int new;
+
+	if (dlg_id_increment == 1) {
+		new = id + 1;
+	} else {
+		new = (((id + dlg_id_increment - dlg_id_offset) / dlg_id_increment)
+			* dlg_id_increment) + dlg_id_offset;
+	}
+	if (unlikely(new == 0)) {
+		new = dlg_id_offset;
+	}
+	return new;
+}
+
+
+/*!
  * \brief Initialize the global dialog table
  * \param size size of the table
  * \return 0 on success, -1 on failure
@@ -326,7 +349,7 @@ int init_dlg_table(unsigned int size)
 
 	for( i=0 ; i<size; i++ ) {
 		memset( &(d_table->entries[i]), 0, sizeof(struct dlg_entry) );
-		d_table->entries[i].next_id = rand() % (3*size);
+		d_table->entries[i].next_id = dlg_next_id(rand() % (3*size));
 		d_table->entries[i].lock_idx = i % d_table->locks_no;
 	}
 
@@ -824,8 +847,9 @@ void link_dlg(struct dlg_cell *dlg, int n, int mode)
 	if(unlikely(mode==0)) dlg_lock( d_table, d_entry);
 
 	/* keep id 0 for special cases */
-	dlg->h_id = 1 + d_entry->next_id++;
-	if(dlg->h_id == 0) dlg->h_id = 1;
+	dlg->h_id = d_entry->next_id;
+	d_entry->next_id += dlg_id_increment;
+	if (unlikely(d_entry->next_id == 0)) d_entry->next_id = dlg_id_offset;
 	LM_DBG("linking dialog [%u:%u]\n", dlg->h_entry, dlg->h_id);
 	if (d_entry->first==0) {
 		d_entry->first = d_entry->last = dlg;
diff --git a/modules/dialog/dlg_hash.h b/modules/dialog/dlg_hash.h
index 57aebb4..66b86e0 100644
--- a/modules/dialog/dlg_hash.h
+++ b/modules/dialog/dlg_hash.h
@@ -232,6 +232,11 @@ int init_dlg_table(unsigned int size);
  */
 void destroy_dlg_table(void);
 
+/*!
+ * \brief Create next id based on offset and increment
+ * \param id current value
+ */
+unsigned int dlg_next_id(unsigned int id);
 
 /*!
  * \brief Create a new dialog structure for a SIP dialog
diff --git a/modules/dialog/doc/dialog_admin.xml b/modules/dialog/doc/dialog_admin.xml
index 6597cd0..008e256 100644
--- a/modules/dialog/doc/dialog_admin.xml
+++ b/modules/dialog/doc/dialog_admin.xml
@@ -1301,6 +1301,51 @@ modparam("dialog", "enable_dmq", 1)
 		</example>
 	</section>
 
+	<section>
+		<title><varname>id_increment</varname> (int)</title>
+		<para>
+			If syncing via DMQ is enabled, this must be set to at least the number of
+			proxies in the pool. Together with the <varname>id_offset</varname> parameter,
+			this will guarantee unique id's in the hash tables.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>1</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>id_increment</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("dialog", "id_increment", 3)
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>id_offset</varname> (int)</title>
+		<para>
+			If syncing via DMQ is enabled, this must be set to a unique number
+			between 1 and the value of <varname>id_increment</varname> (inclusive) for
+			every proxy in the pool. Together with the <varname>id_increment</varname>
+			parameter, this will guarantee unique id's in the hash tables.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>1</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>id_offset</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("dialog", "id_offset", 2)
+...
+</programlisting>
+		</example>
+	</section>
+
 	</section>
 
 




More information about the sr-dev mailing list