Browse code

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.

Alex Hermann authored on 11/08/2014 15:03:31
Showing 5 changed files
... ...
@@ -112,6 +112,8 @@ int initial_cbs_inscript = 1;
112 112
 int dlg_wait_ack = 1;
113 113
 static int dlg_timer_procs = 0;
114 114
 int dlg_enable_dmq = 0;
115
+int dlg_id_offset = 1;
116
+int dlg_id_increment = 1;
115 117
 
116 118
 int dlg_event_rt[DLG_EVENTRT_MAX];
117 119
 
... ...
@@ -297,6 +299,8 @@ static param_export_t mod_params[]={
297 299
 	{ "timeout_noreset",       INT_PARAM, &dlg_timeout_noreset      },
298 300
 	{ "timer_procs",           PARAM_INT, &dlg_timer_procs          },
299 301
 	{ "enable_dmq",            INT_PARAM, &dlg_enable_dmq           },
302
+	{ "id_offset",             INT_PARAM, &dlg_id_offset            },
303
+	{ "id_increment",          INT_PARAM, &dlg_id_increment         },
300 304
 	{ 0,0,0 }
301 305
 };
302 306
 
... ...
@@ -516,6 +520,16 @@ static int mod_init(void)
516 520
 		return -1;
517 521
 	}
518 522
 
523
+	if (dlg_id_increment < 1) {
524
+		LM_ERR("invalid value for id_increment\n");
525
+		return -1;
526
+	}
527
+
528
+	if (dlg_id_offset < 1 || dlg_id_offset > dlg_id_increment) {
529
+		LM_ERR("invalid value for id_offset\n");
530
+		return -1;
531
+	}
532
+
519 533
 	if (timeout_spec.s) {
520 534
 		if ( pv_parse_spec(&timeout_spec, &timeout_avp)==0 
521 535
 				&& (timeout_avp.type!=PVT_AVP)){
... ...
@@ -304,7 +304,6 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
304 304
 	str cseq1, cseq2, contact1, contact2, rroute1, rroute2;
305 305
 	str toroute_name;
306 306
 	str xdata;
307
-	unsigned int next_id;
308 307
 	srjson_doc_t jdoc;
309 308
 	
310 309
 	res = 0;
... ...
@@ -363,10 +362,9 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
363 362
 			link_dlg(dlg, 0, 0);
364 363
 
365 364
 			dlg->h_id = VAL_INT(values+1);
366
-			next_id = d_table->entries[dlg->h_entry].next_id;
367
-
368
-			d_table->entries[dlg->h_entry].next_id =
369
-				(next_id < dlg->h_id) ? (dlg->h_id+1) : next_id;
365
+			if (dlg->h_id >= d_table->entries[dlg->h_entry].next_id) {
366
+				d_table->entries[dlg->h_entry].next_id = dlg_next_id(dlg->h_id);
367
+			}
370 368
 
371 369
 			GET_STR_VALUE(to_tag, values, 6, 1, 1);
372 370
 
... ...
@@ -69,6 +69,8 @@
69 69
 
70 70
 extern int dlg_ka_interval;
71 71
 extern int dlg_enable_dmq;
72
+extern int dlg_id_offset;
73
+extern int dlg_id_increment;
72 74
 
73 75
 /*! global dialog table */
74 76
 struct dlg_table *d_table = 0;
... ...
@@ -264,6 +266,27 @@ int dlg_clean_run(ticks_t ti)
264 266
 	return 0;
265 267
 }
266 268
 
269
+/*!
270
+ * \brief Create next id based on offset and increment
271
+ * \param id current value
272
+ */
273
+unsigned int inline dlg_next_id(unsigned int id)
274
+{
275
+	unsigned int new;
276
+
277
+	if (dlg_id_increment == 1) {
278
+		new = id + 1;
279
+	} else {
280
+		new = (((id + dlg_id_increment - dlg_id_offset) / dlg_id_increment)
281
+			* dlg_id_increment) + dlg_id_offset;
282
+	}
283
+	if (unlikely(new == 0)) {
284
+		new = dlg_id_offset;
285
+	}
286
+	return new;
287
+}
288
+
289
+
267 290
 /*!
268 291
  * \brief Initialize the global dialog table
269 292
  * \param size size of the table
... ...
@@ -326,7 +349,7 @@ int init_dlg_table(unsigned int size)
326 349
 
327 350
 	for( i=0 ; i<size; i++ ) {
328 351
 		memset( &(d_table->entries[i]), 0, sizeof(struct dlg_entry) );
329
-		d_table->entries[i].next_id = rand() % (3*size);
352
+		d_table->entries[i].next_id = dlg_next_id(rand() % (3*size));
330 353
 		d_table->entries[i].lock_idx = i % d_table->locks_no;
331 354
 	}
332 355
 
... ...
@@ -824,8 +847,9 @@ void link_dlg(struct dlg_cell *dlg, int n, int mode)
824 847
 	if(unlikely(mode==0)) dlg_lock( d_table, d_entry);
825 848
 
826 849
 	/* keep id 0 for special cases */
827
-	dlg->h_id = 1 + d_entry->next_id++;
828
-	if(dlg->h_id == 0) dlg->h_id = 1;
850
+	dlg->h_id = d_entry->next_id;
851
+	d_entry->next_id += dlg_id_increment;
852
+	if (unlikely(d_entry->next_id == 0)) d_entry->next_id = dlg_id_offset;
829 853
 	LM_DBG("linking dialog [%u:%u]\n", dlg->h_entry, dlg->h_id);
830 854
 	if (d_entry->first==0) {
831 855
 		d_entry->first = d_entry->last = dlg;
... ...
@@ -232,6 +232,11 @@ int init_dlg_table(unsigned int size);
232 232
  */
233 233
 void destroy_dlg_table(void);
234 234
 
235
+/*!
236
+ * \brief Create next id based on offset and increment
237
+ * \param id current value
238
+ */
239
+unsigned int dlg_next_id(unsigned int id);
235 240
 
236 241
 /*!
237 242
  * \brief Create a new dialog structure for a SIP dialog
... ...
@@ -1301,6 +1301,51 @@ modparam("dialog", "enable_dmq", 1)
1301 1301
 		</example>
1302 1302
 	</section>
1303 1303
 
1304
+	<section>
1305
+		<title><varname>id_increment</varname> (int)</title>
1306
+		<para>
1307
+			If syncing via DMQ is enabled, this must be set to at least the number of
1308
+			proxies in the pool. Together with the <varname>id_offset</varname> parameter,
1309
+			this will guarantee unique id&apos;s in the hash tables.
1310
+		</para>
1311
+		<para>
1312
+		<emphasis>
1313
+			Default value is <quote>1</quote>.
1314
+		</emphasis>
1315
+		</para>
1316
+		<example>
1317
+		<title>Set <varname>id_increment</varname> parameter</title>
1318
+		<programlisting format="linespecific">
1319
+...
1320
+modparam("dialog", "id_increment", 3)
1321
+...
1322
+</programlisting>
1323
+		</example>
1324
+	</section>
1325
+
1326
+	<section>
1327
+		<title><varname>id_offset</varname> (int)</title>
1328
+		<para>
1329
+			If syncing via DMQ is enabled, this must be set to a unique number
1330
+			between 1 and the value of <varname>id_increment</varname> (inclusive) for
1331
+			every proxy in the pool. Together with the <varname>id_increment</varname>
1332
+			parameter, this will guarantee unique id&apos;s in the hash tables.
1333
+		</para>
1334
+		<para>
1335
+		<emphasis>
1336
+			Default value is <quote>1</quote>.
1337
+		</emphasis>
1338
+		</para>
1339
+		<example>
1340
+		<title>Set <varname>id_offset</varname> parameter</title>
1341
+		<programlisting format="linespecific">
1342
+...
1343
+modparam("dialog", "id_offset", 2)
1344
+...
1345
+</programlisting>
1346
+		</example>
1347
+	</section>
1348
+
1304 1349
 	</section>
1305 1350
 
1306 1351