Browse code

pdt: refactored prefix-domain translation

- use internally a function that can take the source domain as parameter
- new function to config pd_translate(sdomain, flags) to allow source
domain to be given from config file

Elena-Ramona Modroiu authored on 20/12/2011 16:58:42
Showing 2 changed files
... ...
@@ -15,4 +15,5 @@ DEFS+=-DOPENSER_MOD_INTERFACE
15 15
 SERLIBPATH=../../lib
16 16
 SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1
17 17
 SER_LIBS+=$(SERLIBPATH)/kmi/kmi
18
+SER_LIBS+=$(SERLIBPATH)/kcore/kcore
18 19
 include ../../Makefile.modules
... ...
@@ -41,6 +41,7 @@
41 41
 #include <stdlib.h>
42 42
 
43 43
 #include "../../lib/srdb1/db_op.h"
44
+#include "../../lib/kcore/parser_helpers.h"
44 45
 #include "../../sr_module.h"
45 46
 #include "../../lib/srdb1/db.h"
46 47
 #include "../../mem/shm_mem.h"
... ...
@@ -79,8 +80,8 @@ static str prefix_column  = str_init("prefix");
79 79
 static str domain_column  = str_init("domain");
80 80
 static int pdt_check_domain  = 1;
81 81
 
82
-/** pstn prefix */
83
-str prefix = {"", 0};
82
+/** translation prefix */
83
+str pdt_prefix = {"", 0};
84 84
 /* List of allowed chars for a prefix*/
85 85
 str pdt_char_list = {"0123456789", 10};
86 86
 
... ...
@@ -95,7 +96,10 @@ static int  w_prefix2domain_2(struct sip_msg* msg, char* mode, char* sd_en);
95 95
 static int  mod_init(void);
96 96
 static void mod_destroy(void);
97 97
 static int  child_init(int rank);
98
-static int prefix2domain(struct sip_msg*, int mode, int sd_en);
98
+static int  pd_translate(sip_msg_t *msg, str *sdomain, int rmode, int fmode);
99
+
100
+static int  w_pd_translate(struct sip_msg* msg, char* str1, char* str2);
101
+static int fixup_translate(void** param, int param_no);
99 102
 
100 103
 static int update_new_uri(struct sip_msg *msg, int plen, str *d, int mode);
101 104
 
... ...
@@ -106,6 +110,8 @@ static cmd_export_t cmds[]={
106 106
 		0, REQUEST_ROUTE|FAILURE_ROUTE},
107 107
 	{"prefix2domain", (cmd_function)w_prefix2domain_2, 2, fixup_igp_igp,
108 108
 		0, REQUEST_ROUTE|FAILURE_ROUTE},
109
+	{"pd_translate", (cmd_function)w_pd_translate,     2, fixup_translate,
110
+		0, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
109 111
 	{0, 0, 0, 0, 0, 0}
110 112
 };
111 113
 
... ...
@@ -115,7 +121,7 @@ static param_export_t params[]={
115 115
 	{"sdomain_column", STR_PARAM, &sdomain_column.s},
116 116
 	{"prefix_column",  STR_PARAM, &prefix_column.s},
117 117
 	{"domain_column",  STR_PARAM, &domain_column.s},
118
-	{"prefix",         STR_PARAM, &prefix.s},
118
+	{"prefix",         STR_PARAM, &pdt_prefix.s},
119 119
 	{"char_list",      STR_PARAM, &pdt_char_list.s},
120 120
 	{"fetch_rows",     INT_PARAM, &pdt_fetch_rows},
121 121
 	{"check_domain",   INT_PARAM, &pdt_check_domain},
... ...
@@ -155,7 +161,7 @@ static int mod_init(void)
155 155
 	sdomain_column.len = strlen(sdomain_column.s);
156 156
 	prefix_column.len = strlen(prefix_column.s);
157 157
 	domain_column.len = strlen(domain_column.s);
158
-	prefix.len = strlen(prefix.s);
158
+	pdt_prefix.len = strlen(pdt_prefix.s);
159 159
 
160 160
 	if(pdt_fetch_rows<=0)
161 161
 		pdt_fetch_rows = 1000;
... ...
@@ -292,28 +298,32 @@ static void mod_destroy(void)
292 292
 
293 293
 static int w_prefix2domain(struct sip_msg* msg, char* str1, char* str2)
294 294
 {
295
-	return prefix2domain(msg, 0, 0);
295
+	str sdall={"*",1};
296
+	return pd_translate(msg, &sdall, 0, 0);
296 297
 }
297 298
 
298 299
 static int w_prefix2domain_1(struct sip_msg* msg, char* mode, char* str2)
299 300
 {
300
-	int m;
301
+	str sdall={"*",1};
302
+	int md;
301 303
 
302
-	if(fixup_get_ivalue(msg, (gparam_p)mode, &m)!=0)
304
+	if(fixup_get_ivalue(msg, (gparam_p)mode, &md)!=0)
303 305
 	{
304 306
 		LM_ERR("no mode value\n");
305 307
 		return -1;
306 308
 	}
307 309
 
308
-	if(m!=1 && m!=2)
309
-		m = 0;
310
+	if(md!=1 && md!=2)
311
+		md = 0;
310 312
 
311
-	return prefix2domain(msg, m, 0);
313
+	return pd_translate(msg, &sdall, md, 0);
312 314
 }
313 315
 
314 316
 static int w_prefix2domain_2(struct sip_msg* msg, char* mode, char* sdm)
315 317
 {
316
-	int m, s;
318
+	int m, s, f;
319
+	str sdomain={"*",1};
320
+	sip_uri_t *furi;
317 321
 
318 322
 	if(fixup_get_ivalue(msg, (gparam_p)mode, &m)!=0)
319 323
 	{
... ...
@@ -333,15 +343,36 @@ static int w_prefix2domain_2(struct sip_msg* msg, char* mode, char* sdm)
333 333
 	if(s!=1 && s!=2)
334 334
 		s = 0;
335 335
 
336
-	return prefix2domain(msg, m, s);
336
+	f = 0;
337
+	if(s==1 || s==2)
338
+	{
339
+		/* take the domain from  FROM uri as sdomain */
340
+		if((furi = parse_from_uri(msg))==NULL)
341
+		{
342
+			LM_ERR("cannot parse FROM header URI\n");
343
+			return -1;
344
+		}
345
+		sdomain = furi->host;
346
+		if(s==2)
347
+			f = 1;
348
+	}
349
+	return pd_translate(msg, &sdomain, m, f);
337 350
 }
338 351
 
339
-/* change the r-uri if it is a PSTN format */
340
-static int prefix2domain(struct sip_msg* msg, int mode, int sd_en)
352
+/**
353
+ * @brief change the r-uri domain based on source domain and prefix
354
+ *
355
+ * @param msg the sip message structure
356
+ * @param sdomain the source domain
357
+ * @param rmode the r-uri rewrite mode
358
+ * @param fmode the source domain fallback mode
359
+ * @return 1 if translation is done; -1 otherwise
360
+ */
361
+static int pd_translate(sip_msg_t *msg, str *sdomain, int rmode, int fmode)
341 362
 {
342
-	str *d, p, all={"*",1};
363
+	str *d, p;
364
+	str sdall={"*",1};
343 365
 	int plen;
344
-	struct sip_uri uri;
345 366
 	
346 367
 	if(msg==NULL)
347 368
 	{
... ...
@@ -349,45 +380,36 @@ static int prefix2domain(struct sip_msg* msg, int mode, int sd_en)
349 349
 		return -1;
350 350
 	}
351 351
 	
352
-	/* parse the uri, if not yet */
353
-	if(msg->parsed_uri_ok==0)
354
-		if(parse_sip_msg_uri(msg)<0)
355
-		{
356
-			LM_ERR("failed to parse the R-URI\n");
357
-			return -1;
358
-		}
352
+	if(parse_sip_msg_uri(msg)<0)
353
+	{
354
+		LM_ERR("failed to parse the R-URI\n");
355
+		return -1;
356
+	}
359 357
 
360
-    /* if the user part begin with the prefix for PSTN users, extract the code*/
358
+    /* if the user part begin with the prefix, extract the code*/
361 359
 	if (msg->parsed_uri.user.len<=0)
362 360
 	{
363 361
 		LM_DBG("user part of the message is empty\n");
364 362
 		return -1;
365 363
 	}   
366 364
     
367
-	if(prefix.len>0)
365
+	if(pdt_prefix.len>0)
368 366
 	{
369
-		if (msg->parsed_uri.user.len<=prefix.len)
367
+		if (msg->parsed_uri.user.len<=pdt_prefix.len)
370 368
 		{
371
-			LM_DBG("user part is less than prefix\n");
369
+			LM_DBG("user part is less than prefix parameter\n");
372 370
 			return -1;
373 371
 		}   
374
-		if(strncasecmp(prefix.s, msg->parsed_uri.user.s, prefix.len)!=0)
372
+		if(strncasecmp(pdt_prefix.s, msg->parsed_uri.user.s,
373
+					pdt_prefix.len)!=0)
375 374
 		{
376
-			LM_DBG("PSTN prefix did not matched\n");
375
+			LM_DBG("prefix parameter did not matched\n");
377 376
 			return -1;
378 377
 		}
379 378
 	}   
380 379
 	
381
-	if(prefix.len>0 && prefix.len < msg->parsed_uri.user.len
382
-			&& strncasecmp(prefix.s, msg->parsed_uri.user.s, prefix.len)!=0)
383
-	{
384
-		LM_DBG("PSTN prefix did not matched\n");
385
-		return -1;
386
-			
387
-	}
388
-
389
-	p.s   = msg->parsed_uri.user.s + prefix.len;
390
-	p.len = msg->parsed_uri.user.len - prefix.len;
380
+	p.s   = msg->parsed_uri.user.s + pdt_prefix.len;
381
+	p.len = msg->parsed_uri.user.len - pdt_prefix.len;
391 382
 
392 383
 again:
393 384
 	lock_get( pdt_lock );
... ...
@@ -399,69 +421,20 @@ again:
399 399
 	pdt_tree_refcnt++;
400 400
 	lock_release( pdt_lock );
401 401
 
402
-	if(sd_en==2)
403
-	{	
404
-		/* take the domain from  FROM uri as sdomain */
405
-		if(parse_from_header(msg)<0 ||  msg->from == NULL 
406
-				|| get_from(msg)==NULL)
407
-		{
408
-			LM_ERR("cannot parse FROM header\n");
409
-			goto error;
410
-		}	
411
-		
412
-		memset(&uri, 0, sizeof(struct sip_uri));
413
-		if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len , &uri)<0)
414
-		{
415
-			LM_ERR("failed to parse From uri\n");
416
-			goto error;
417
-		}
418
-	
419
-		/* find the domain that corresponds to this prefix */
420
-		plen = 0;
421
-		if((d=pdt_get_domain(*_ptree, &uri.host, &p, &plen))==NULL)
422
-		{
423
-			plen = 0;
424
-			if((d=pdt_get_domain(*_ptree, &all, &p, &plen))==NULL)
425
-			{
426
-				LM_INFO("no prefix found in [%.*s]\n", p.len, p.s);
427
-				goto error;
428
-			}
429
-		}
430
-	} else if(sd_en==1) {	
431
-		/* take the domain from  FROM uri as sdomain */
432
-		if(parse_from_header(msg)<0 ||  msg->from == NULL
433
-				|| get_from(msg)==NULL)
434
-		{
435
-			LM_ERR("ERROR cannot parse FROM header\n");
436
-			goto error;
437
-		}	
438
-		
439
-		memset(&uri, 0, sizeof(struct sip_uri));
440
-		if (parse_uri(get_from(msg)->uri.s, get_from(msg)->uri.len , &uri)<0)
441
-		{
442
-			LM_ERR("failed to parse From uri\n");
443
-			goto error;
444
-		}
445
-	
446
-		/* find the domain that corresponds to this prefix */
447
-		plen = 0;
448
-		if((d=pdt_get_domain(*_ptree, &uri.host, &p, &plen))==NULL)
449
-		{
450
-			LM_INFO("no prefix found in [%.*s]\n", p.len, p.s);
451
-			goto error;
452
-		}
453
-	} else {
454
-		/* find the domain that corresponds to this prefix */
402
+
403
+	if((d=pdt_get_domain(*_ptree, sdomain, &p, &plen))==NULL)
404
+	{
455 405
 		plen = 0;
456
-		if((d=pdt_get_domain(*_ptree, &all, &p, &plen))==NULL)
406
+		if((fmode==0) || (d=pdt_get_domain(*_ptree, &sdall, &p, &plen))==NULL)
457 407
 		{
458
-			LM_INFO("no prefix found in [%.*s]\n", p.len, p.s);
408
+			LM_INFO("no prefix PDT prefix matched [%.*s]\n", p.len, p.s);
459 409
 			goto error;
460 410
 		}
461 411
 	}
412
+
462 413
 	
463 414
 	/* update the new uri */
464
-	if(update_new_uri(msg, plen, d, mode)<0)
415
+	if(update_new_uri(msg, plen, d, rmode)<0)
465 416
 	{
466 417
 		LM_ERR("new_uri cannot be updated\n");
467 418
 		goto error;
... ...
@@ -479,7 +452,48 @@ error:
479 479
 	return -1;
480 480
 }
481 481
 
482
-/* change the uri according to translation of the prefix */
482
+/**
483
+ *
484
+ */
485
+static int fixup_translate(void** param, int param_no)
486
+{
487
+	if(param_no==1)
488
+		return fixup_spve_null(param, 1);
489
+	if(param_no==2)
490
+		return fixup_igp_null(param, 1);
491
+	return 0;
492
+}
493
+
494
+/**
495
+ *
496
+ */
497
+static int w_pd_translate(sip_msg_t* msg, char* sdomain, char* mode)
498
+{
499
+	int md;
500
+	str sd;
501
+
502
+	if(fixup_get_svalue(msg, (gparam_p)sdomain, &sd)!=0)
503
+	{
504
+		LM_ERR("no source domain value\n");
505
+		return -1;
506
+	}
507
+
508
+
509
+	if(fixup_get_ivalue(msg, (gparam_p)mode, &md)!=0)
510
+	{
511
+		LM_ERR("no multi-domain mode value\n");
512
+		return -1;
513
+	}
514
+
515
+	if(md!=1 && md!=2)
516
+		md = 0;
517
+
518
+	return pd_translate(msg, &sd, md, 0);
519
+}
520
+
521
+/**
522
+ * change the uri according to update mode
523
+ */
483 524
 static int update_new_uri(struct sip_msg *msg, int plen, str *d, int mode)
484 525
 {
485 526
 	struct action act;
... ...
@@ -490,26 +504,26 @@ static int update_new_uri(struct sip_msg *msg, int plen, str *d, int mode)
490 490
 		return -1;
491 491
 	}
492 492
 	
493
-	if(mode==0 || (mode==1 && prefix.len>0))
493
+	if(mode==0 || (mode==1 && pdt_prefix.len>0))
494 494
 	{
495 495
 		memset(&act, '\0', sizeof(act));
496 496
 		act.type = STRIP_T;
497 497
 		act.val[0].type = NUMBER_ST;
498 498
 		if(mode==0)
499
-			act.val[0].u.number = plen + prefix.len;
499
+			act.val[0].u.number = plen + pdt_prefix.len;
500 500
 		else
501
-			act.val[0].u.number = prefix.len;
501
+			act.val[0].u.number = pdt_prefix.len;
502 502
 
503 503
 		init_run_actions_ctx(&ra_ctx);
504 504
 		if (do_action(&ra_ctx, &act, msg) < 0)
505 505
 		{
506
-			LM_ERR("failed to remove prefix\n");
506
+			LM_ERR("failed to remove prefix parameter\n");
507 507
 			return -1;
508 508
 		}
509 509
 	}
510 510
 	
511 511
 	memset(&act, '\0', sizeof(act));
512
-	act.type = SET_HOSTPORT_T;
512
+	act.type = SET_HOSTALL_T;
513 513
 	act.val[0].type = STRING_ST;
514 514
 	act.val[0].u.string = d->s;
515 515
 	init_run_actions_ctx(&ra_ctx);