Browse code

registrar : add optional params to registered function

3rd parameter as flag is used to optionally restrict contacts when searching.
values are
1 - match_callid
2 - match_received
3 - match_contact

4th parameter as flag to optionally perform action on positive match
values are
1 - set xavp_rcd with value from matched contact

Luis Azedo authored on 25/03/2015 11:21:21
Showing 5 changed files
... ...
@@ -659,6 +659,11 @@ modparam("registrar", "path_check_local", 1)
659 659
 	<section id="registrar.p.reg_callid_avp">
660 660
 		<title><varname>reg_callid_avp</varname> (string)</title>
661 661
 		<para>
662
+			<emphasis>
663
+				obsolete. use match_option in registered function
664
+			</emphasis>
665
+		</para>
666
+		<para>
662 667
 		If reg_callid_avp is defined and populated when the
663 668
 		<function>registered()</function> is invoked, the result is 
664 669
 		TRUE only if an active registration with
... ...
@@ -1102,7 +1107,7 @@ lookup_branches("location");
1102 1102
 
1103 1103
 	<section id="registrar.f.registered">
1104 1104
 		<title>
1105
-		<function moreinfo="none">registered(domain [, uri])</function>
1105
+		<function moreinfo="none">registered(domain [, uri [, match_option [, match_action]]])</function>
1106 1106
 		</title>
1107 1107
 		<para>
1108 1108
 		The function returns true if the AOR in the Request-URI is 
... ...
@@ -1124,6 +1129,35 @@ lookup_branches("location");
1124 1124
 			of R-URI. It can be a dynamic string with pseudo-variables.
1125 1125
 			</para>
1126 1126
 		</listitem>
1127
+		<listitem>
1128
+			<para>
1129
+			<emphasis>match_option</emphasis> (optional) - flag parameter to restrict
1130
+			contact search. use reg_xavp_cfg to set the values to compare to.
1131
+			</para>
1132
+            <para>flag values is as follows:</para>
1133
+			<itemizedlist>
1134
+				<listitem>
1135
+					<para>1 - match_callid</para>
1136
+				</listiem>
1137
+				<listitem>
1138
+					<para>2 - match_received</para>
1139
+				</listiem>
1140
+				<listitem>
1141
+					<para>4 - match_contact</para>
1142
+				</listiem>
1143
+			</itemizedlist>			
1144
+		</listitem>
1145
+		<listitem>
1146
+			<para>
1147
+			<emphasis>match_action</emphasis> (optional) - actions to perform when match is positive.
1148
+			</para>
1149
+            <para>flag values is as follows:</para>
1150
+			<itemizedlist>
1151
+				<listitem>
1152
+					<para>1 - set xavp_rcd with value from matched contact</para>
1153
+				</listiem>
1154
+			</itemizedlist>						
1155
+		</listitem>
1127 1156
 		</itemizedlist>
1128 1157
 		<para>
1129 1158
 		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
... ...
@@ -1137,6 +1171,13 @@ if (registered("location")) {
1137 1137
 	...
1138 1138
 };
1139 1139
 ...
1140
+$xavp(regcfg=>match_received) = $su;
1141
+if (registered("location","$rz:$Au", 2)) {
1142
+	sl_send_reply("100", "Trying");
1143
+	...
1144
+};
1145
+...
1146
+
1140 1147
 </programlisting>
1141 1148
 		</example>
1142 1149
 	</section>
... ...
@@ -619,13 +619,24 @@ done:
619 619
  * it is similar to lookup but registered neither rewrites
620 620
  * the Request-URI nor appends branches
621 621
  */
622
-int registered(struct sip_msg* _m, udomain_t* _d, str* _uri)
622
+int registered(struct sip_msg* _m, udomain_t* _d, str* _uri) {
623
+	return registered4(_m, _d, _uri, 0, 0);
624
+}
625
+
626
+int registered3(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag) {
627
+	return registered4(_m, _d, _uri, match_flag, 0);
628
+}
629
+
630
+int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, int match_action_flag)
623 631
 {
624 632
 	str uri, aor;
625 633
 	urecord_t* r;
626 634
 	ucontact_t* ptr;
627 635
 	int res;
628
-	int_str match_callid=(int_str)0;
636
+	str match_callid = {0,0};
637
+	str match_received = {0,0};
638
+	str match_contact = {0,0};
639
+	sr_xavp_t *vavp = NULL;
629 640
 
630 641
 	if(_uri!=NULL)
631 642
 	{
... ...
@@ -650,26 +661,61 @@ int registered(struct sip_msg* _m, udomain_t* _d, str* _uri)
650 650
 	}
651 651
 
652 652
 	if (res == 0) {
653
-		
654
-		if (reg_callid_avp_name.n) {
655
-			struct usr_avp *avp =
656
-				search_first_avp( reg_callid_avp_type, reg_callid_avp_name, &match_callid, 0);
657
-			if (!(avp && is_avp_str_val(avp)))
658
-				match_callid.n = 0;
659
-				match_callid.s.s = NULL;
660
-		} else {
661
-			match_callid.n = 0;
662
-			match_callid.s.s = NULL;
653
+		LM_DBG("searching with match flags (%d,%d)\n", match_flag, reg_match_flag_param);
654
+		if(reg_xavp_cfg.s!=NULL) {
655
+
656
+			if((match_flag & 1)
657
+					&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_callid_name)) != NULL
658
+					&& vavp->val.v.s.len > 0) {
659
+				match_callid = vavp->val.v.s;
660
+				LM_DBG("matching with callid %.*s\n", match_callid.len, match_callid.s);
661
+			}
662
+
663
+			if((match_flag & 2)
664
+					&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_received_name)) != NULL
665
+					&& vavp->val.v.s.len > 0) {
666
+				match_received = vavp->val.v.s;
667
+				LM_DBG("matching with received %.*s\n", match_received.len, match_received.s);
668
+			}
669
+
670
+			if((match_flag & 4)
671
+					&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_contact_name)) != NULL
672
+					&& vavp->val.v.s.len > 0) {
673
+				match_contact = vavp->val.v.s;
674
+				LM_DBG("matching with contact %.*s\n", match_contact.len, match_contact.s);
675
+			}
663 676
 		}
664 677
 
665 678
 		for (ptr = r->contacts; ptr; ptr = ptr->next) {
666 679
 			if(!VALID_CONTACT(ptr, act_time)) continue;
667
-			if (match_callid.s.s && /* optionally enforce tighter matching w/ Call-ID */
668
-				memcmp(match_callid.s.s,ptr->callid.s,match_callid.s.len))
680
+			if (match_callid.s && /* optionally enforce tighter matching w/ Call-ID */
681
+				match_callid.len > 0 &&
682
+				(match_callid.len != ptr->callid.len || 
683
+				memcmp(match_callid.s, ptr->callid.s, match_callid.len)))
684
+				continue;
685
+			if (match_received.s && /* optionally enforce tighter matching w/ ip:port */
686
+				match_received.len > 0 &&
687
+				(match_received.len != ptr->received.len || 
688
+				memcmp(match_received.s, ptr->received.s, match_received.len)))
669 689
 				continue;
690
+			if (match_contact.s && /* optionally enforce tighter matching w/ Contact */
691
+				match_contact.len > 0 &&
692
+				(match_contact.len != ptr->c.len || 
693
+				memcmp(match_contact.s, ptr->c.s, match_contact.len)))
694
+				continue;
695
+
696
+			if(ptr->xavp!=NULL && match_action_flag == 1) {
697
+				sr_xavp_t *xavp = xavp_clone_level_nodata(ptr->xavp);
698
+				if(xavp_add(xavp, NULL)<0) {
699
+					LM_ERR("error adding xavp for %.*s after successful match\n", aor.len, ZSW(aor.s));
700
+					xavp_destroy_list(&xavp);
701
+				}
702
+			}
703
+
670 704
 			ul.release_urecord(r);
671 705
 			ul.unlock_udomain(_d, &aor);
672 706
 			LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));
707
+
673 708
 			return 1;
674 709
 		}
675 710
 	}
... ...
@@ -67,6 +67,7 @@ int lookup_branches(sip_msg_t *msg, udomain_t *d);
67 67
  * the Request-URI nor appends branches
68 68
  */
69 69
 int registered(struct sip_msg* _m, udomain_t* _d, str* _uri);
70
-
70
+int registered3(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag);
71
+int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, int match_action_flag);
71 72
 
72 73
 #endif /* LOOKUP_H */
... ...
@@ -101,10 +101,9 @@ int reg_outbound_mode = 0;
101 101
 int reg_regid_mode = 0;
102 102
 int reg_flow_timer = 0;
103 103
 
104
-/* Populate this AVP if testing for specific registration instance. */
105
-char *reg_callid_avp_param = 0;
106
-unsigned short reg_callid_avp_type = 0;
107
-int_str reg_callid_avp_name;
104
+str match_callid_name = str_init("match_callid");
105
+str match_received_name = str_init("match_received");
106
+str match_contact_name = str_init("match_contact");
108 107
 
109 108
 char* rcv_avp_param = 0;
110 109
 unsigned short rcv_avp_type = 0;
... ...
@@ -164,6 +163,10 @@ static cmd_export_t cmds[] = {
164 164
 			REQUEST_ROUTE | FAILURE_ROUTE },
165 165
 	{"registered",   (cmd_function)w_registered,  2,  domain_uri_fixup, 0,
166 166
 			REQUEST_ROUTE | FAILURE_ROUTE },
167
+	{"registered",   (cmd_function)w_registered3, 3,  registered_fixup, 0,
168
+			REQUEST_ROUTE | FAILURE_ROUTE },
169
+	{"registered",   (cmd_function)w_registered4, 4,  registered_fixup, 0,
170
+			REQUEST_ROUTE | FAILURE_ROUTE },
167 171
 	{"add_sock_hdr", (cmd_function)add_sock_hdr,  1,  fixup_str_null, 0,
168 172
 			REQUEST_ROUTE },
169 173
 	{"unregister",   (cmd_function)w_unregister,  2,  unreg_fixup, 0,
... ...
@@ -200,7 +203,6 @@ static param_export_t params[] = {
200 200
 	{"max_expires",        INT_PARAM, &default_registrar_cfg.max_expires			},
201 201
 	{"received_param",     PARAM_STR, &rcv_param           					},
202 202
 	{"received_avp",       PARAM_STRING, &rcv_avp_param       					},
203
-	{"reg_callid_avp",     PARAM_STRING, &reg_callid_avp_param					},
204 203
 	{"max_contacts",       INT_PARAM, &default_registrar_cfg.max_contacts			},
205 204
 	{"retry_after",        INT_PARAM, &default_registrar_cfg.retry_after			},
206 205
 	{"sock_flag",          INT_PARAM, &sock_flag           					},
... ...
@@ -209,7 +211,7 @@ static param_export_t params[] = {
209 209
 	{"use_path",           INT_PARAM, &path_enabled        					},
210 210
 	{"path_mode",          INT_PARAM, &path_mode           					},
211 211
 	{"path_use_received",  INT_PARAM, &path_use_params     					},
212
-        {"path_check_local",   INT_PARAM, &path_check_local                                     },
212
+	{"path_check_local",   INT_PARAM, &path_check_local                                     },
213 213
 	{"xavp_cfg",           PARAM_STR, &reg_xavp_cfg     					},
214 214
 	{"xavp_rcd",           PARAM_STR, &reg_xavp_rcd     					},
215 215
 	{"gruu_enabled",       INT_PARAM, &reg_gruu_enabled    					},
... ...
@@ -306,24 +308,6 @@ static int mod_init(void)
306 306
 		rcv_avp_type = 0;
307 307
 	}
308 308
 
309
-	if (reg_callid_avp_param && *reg_callid_avp_param) {
310
-		s.s = reg_callid_avp_param; s.len = strlen(s.s);
311
-		if (pv_parse_spec(&s, &avp_spec)==0
312
-			|| avp_spec.type!=PVT_AVP) {
313
-			LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param);
314
-			return -1;
315
-		}
316
-
317
-		if(pv_get_avp_name(0, &avp_spec.pvp, &reg_callid_avp_name, &reg_callid_avp_type)!=0)
318
-		{
319
-			LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param);
320
-			return -1;
321
-		}
322
-	} else {
323
-		reg_callid_avp_name.n = 0;
324
-		reg_callid_avp_type = 0;
325
-	}
326
-
327 309
 	bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
328 310
 	if (!bind_usrloc) {
329 311
 		LM_ERR("can't bind usrloc\n");
... ...
@@ -488,6 +472,46 @@ static int w_registered(struct sip_msg* _m, char* _d, char* _uri)
488 488
 	return registered(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL);
489 489
 }
490 490
 
491
+static int w_registered3(struct sip_msg* _m, char* _d, char* _uri, char* _flags)
492
+{
493
+	str uri = {0};
494
+	int flags = 0;
495
+	if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
496
+	{
497
+		LM_ERR("invalid uri parameter\n");
498
+		return -1;
499
+	}
500
+	if(_flags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_flags, &flags)) < 0)
501
+	{
502
+		LM_ERR("invalid flags parameter\n");
503
+		return -1;
504
+	}
505
+	return registered3(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL, flags);
506
+}
507
+
508
+static int w_registered4(struct sip_msg* _m, char* _d, char* _uri, char* _flags, char* _actionflags)
509
+{
510
+	str uri = {0};
511
+	int flags = 0;
512
+	int actionflags = 0;
513
+	if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
514
+	{
515
+		LM_ERR("invalid uri parameter\n");
516
+		return -1;
517
+	}
518
+	if(_flags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_flags, &flags)) < 0)
519
+	{
520
+		LM_ERR("invalid flags parameter\n");
521
+		return -1;
522
+	}
523
+	if(_actionflags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_actionflags, &actionflags)) < 0)
524
+	{
525
+		LM_ERR("invalid action flag parameter\n");
526
+		return -1;
527
+	}
528
+	return registered4(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL, flags, actionflags);
529
+}
530
+
491 531
 static int w_unregister(struct sip_msg* _m, char* _d, char* _uri)
492 532
 {
493 533
 	str uri = {0};
... ...
@@ -550,6 +574,19 @@ static int domain_uri_fixup(void** param, int param_no)
550 550
 	return 0;
551 551
 }
552 552
 
553
+static int registered_fixup(void** param, int param_no)
554
+{
555
+	if (param_no == 1) {
556
+		return domain_fixup(param, 1);
557
+	} else if (param_no == 2) {
558
+		return fixup_spve_null(param, 1);
559
+	} else if (param_no == 3) {
560
+		return fixup_igp_null(param, 1);
561
+	} else if (param_no == 4) {
562
+		return fixup_igp_null(param, 1);
563
+	}
564
+	return 0;
565
+}
553 566
 
554 567
 /*! \brief
555 568
  * Convert char* parameter to udomain_t* pointer
... ...
@@ -74,8 +74,10 @@ extern float def_q;
74 74
 
75 75
 extern unsigned short rcv_avp_type;
76 76
 extern int_str rcv_avp_name;
77
-extern unsigned short reg_callid_avp_type;
78
-extern int_str reg_callid_avp_name;
77
+
78
+extern str match_callid_name;
79
+extern str match_received_name;
80
+extern str match_contact_name;
79 81
 
80 82
 extern str rcv_param;
81 83
 extern int method_filtering;