Browse code

- new alg 7 to hash the content of param hash_pvar - hash_pvar parameter can be a PV formatted string, updated at runtime - patch by Carsten Bock (closes #1838758)

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@3819 689a6050-402a-0410-94f2-e92a70836424

Daniel-Constantin Mierla authored on 02/03/2008 11:34:42
Showing 4 changed files
... ...
@@ -890,6 +890,35 @@ int ds_hash_authusername(struct sip_msg *msg, unsigned int *hash)
890 890
 	return 0;
891 891
 }
892 892
 
893
+
894
+int ds_hash_pvar(struct sip_msg *msg, unsigned int *hash)
895
+{
896
+	/* The String to create the hash */
897
+	str hash_str = {0, 0};
898
+	
899
+	if(msg==NULL || hash == NULL || hash_param_model == NULL)
900
+	{
901
+		LM_ERR("bad parameters\n");
902
+		return -1;
903
+	}
904
+	if (pv_printf_s(msg, hash_param_model, &hash_str)<0) {
905
+		LM_ERR("error - cannot print the format\n");
906
+		return -1;
907
+	}
908
+
909
+	/* Remove empty spaces */
910
+	trim(&hash_str);
911
+	if (hash_str.len <= 0) {
912
+		LM_ERR("String is empty!\n");
913
+		return -1;
914
+	}
915
+	LM_DBG("Hashing %.*s!\n", hash_str.len, hash_str.s);
916
+
917
+	*hash = ds_get_hash(&hash_str, NULL);
918
+	
919
+	return 0;
920
+}
921
+
893 922
 static inline int ds_get_index(int group, ds_set_p *index)
894 923
 {
895 924
 	ds_set_p si = NULL;
... ...
@@ -1061,6 +1090,13 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
1061 1090
 		case 6:
1062 1091
 			hash = rand() % idx->nr;
1063 1092
 		break;
1093
+		case 7:
1094
+			if (ds_hash_pvar(msg, &hash)!=0)
1095
+			{
1096
+				LM_ERR("can't get PV hash\n");
1097
+				return -1;
1098
+			}
1099
+		break;		
1064 1100
 		default:
1065 1101
 			LM_WARN("algo %d not implemented - using first entry...\n", alg);
1066 1102
 			hash = 0;
... ...
@@ -73,6 +73,8 @@ extern unsigned short grp_avp_type;
73 73
 extern int_str cnt_avp_name;
74 74
 extern unsigned short cnt_avp_type;
75 75
 
76
+extern pv_elem_t * hash_param_model;
77
+
76 78
 /* Structure containing pointers to TM-functions */
77 79
 struct tm_binds tmb;
78 80
 extern str ds_ping_method;
... ...
@@ -67,6 +67,8 @@ int  ds_use_default = 0;
67 67
 static str dst_avp_param = {NULL, 0};
68 68
 static str grp_avp_param = {NULL, 0};
69 69
 static str cnt_avp_param = {NULL, 0};
70
+str hash_pvar_param = {NULL, 0};
71
+
70 72
 int_str dst_avp_name;
71 73
 unsigned short dst_avp_type;
72 74
 int_str grp_avp_name;
... ...
@@ -74,6 +76,8 @@ unsigned short grp_avp_type;
74 76
 int_str cnt_avp_name;
75 77
 unsigned short cnt_avp_type;
76 78
 
79
+pv_elem_t * hash_model_param = NULL;
80
+
77 81
 int probing_threshhold = 3; /* number of failed requests, before a destination
78 82
 							   is taken into probing */
79 83
 str ds_ping_method = {"OPTIONS",7};
... ...
@@ -138,6 +142,7 @@ static param_export_t params[]={
138 142
 	{"dst_avp",         STR_PARAM, &dst_avp_param.s},
139 143
 	{"grp_avp",         STR_PARAM, &grp_avp_param.s},
140 144
 	{"cnt_avp",         STR_PARAM, &cnt_avp_param.s},
145
+	{"hash_pvar",       STR_PARAM, &hash_pvar_param.s},
141 146
 	{"ds_probing_threshhold", INT_PARAM, &probing_threshhold},
142 147
 	{"ds_ping_method",     STR_PARAM, &ds_ping_method.s},
143 148
 	{"ds_ping_from",       STR_PARAM, &ds_ping_from.s},
... ...
@@ -183,6 +188,8 @@ static int mod_init(void)
183 188
 		grp_avp_param.len = strlen(grp_avp_param.s);
184 189
 	if (cnt_avp_param.s)
185 190
 		cnt_avp_param.len = strlen(cnt_avp_param.s);	
191
+	if (hash_pvar_param.s)
192
+		hash_pvar_param.len = strlen(hash_pvar_param.s);	
186 193
 	if (ds_ping_from.s) ds_ping_from.len = strlen(ds_ping_from.s);
187 194
 	if (ds_ping_method.s) ds_ping_method.len = strlen(ds_ping_method.s);
188 195
 
... ...
@@ -274,6 +281,16 @@ static int mod_init(void)
274 281
 		cnt_avp_type = 0;
275 282
 	}
276 283
 
284
+	if (hash_pvar_param.s && *hash_pvar_param.s) {
285
+		if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0
286
+				|| hash_param_model==NULL) {
287
+			LM_ERR("malformed PV string: %s\n", hash_pvar_param.s);
288
+			return -1;
289
+		}		
290
+	} else {
291
+		hash_param_model = NULL;
292
+	}
293
+
277 294
 	/* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */
278 295
 	if (ds_ping_interval > 0)
279 296
 	{
... ...
@@ -326,6 +326,39 @@ modparam("dispatcher", "force_dst", 1)
326 326
  ...
327 327
  modparam("dispatcher", "cnt_avp", "$avp(i:273)")
328 328
  ...
329
+ </programlisting>
330
+ 		</example>
331
+ 	</section>
332
+ 	<section>
333
+ 		<title><varname>hash_pvar</varname> (str)</title>
334
+ 		<para>
335
+ 		String with PVs used for the hashing algorithm 7.
336
+ 		</para>
337
+		<note>
338
+ 		<para>
339
+		You must set this parameter if you want do hashing over custom message
340
+		parts.
341
+ 		</para>
342
+		</note>
343
+ 		<para>
344
+ 		<emphasis>
345
+ 			Default value is <quote>null</quote> - disabled.
346
+ 		</emphasis>
347
+ 		</para>
348
+ 		<example>
349
+ 		<title>Use $avp(i:273) for hashing:</title>
350
+ <programlisting format="linespecific">
351
+ ...
352
+ modparam("dispatcher", "hash_pvar", "$avp(i:273)")
353
+ ...
354
+ </programlisting>
355
+ 		</example>
356
+ 		<example>
357
+ 		<title>Use combination of PVs for hashing:</title>
358
+ <programlisting format="linespecific">
359
+ ...
360
+ modparam("dispatcher", "hash_pvar", "hash the $fU@$ci")
361
+ ...
329 362
  </programlisting>
330 363
  		</example>
331 364
  	</section>
... ...
@@ -473,6 +506,12 @@ modparam("dispatcher", "force_dst", 1)
473 506
 				<quote>6</quote> - random (using rand()).
474 507
 				</para>
475 508
 			</listitem>
509
+			<listitem>
510
+				<para>
511
+				<quote>7</quote> - hash over the content of PVs string.
512
+				Note: This works only when the parameter hash_pvar is set.
513
+				</para>
514
+			</listitem>
476 515
 			<listitem>
477 516
 				<para>
478 517
 				<quote>X</quote> - if the algorithm is not implemented, the