Browse code

Merge pull request #115 from kamailio/lazedo/registrar-registered

registrar : add optional params to registered function

Daniel-Constantin Mierla authored on 26/03/2015 22:26:53
Showing 5 changed files
... ...
@@ -658,6 +658,11 @@ modparam("registrar", "path_check_local", 1)
658 658
 
659 659
 	<section id="registrar.p.reg_callid_avp">
660 660
 		<title><varname>reg_callid_avp</varname> (string)</title>
661
+		<para>
662
+			<emphasis>
663
+				obsolete. use match_option in registered function
664
+			</emphasis>
665
+		</para>
661 666
 		<para>
662 667
 		If reg_callid_avp is defined and populated when the
663 668
 		<function>registered()</function> is invoked, the result is 
... ...
@@ -1102,7 +1107,7 @@ lookup_branches("location");
1102 1107
 
1103 1108
 	<section id="registrar.f.registered">
1104 1109
 		<title>
1105
-		<function moreinfo="none">registered(domain [, uri])</function>
1110
+		<function moreinfo="none">registered(domain [, uri [, match_option [, match_action]]])</function>
1106 1111
 		</title>
1107 1112
 		<para>
1108 1113
 		The function returns true if the AOR in the Request-URI is 
... ...
@@ -1124,6 +1129,35 @@ lookup_branches("location");
1124 1129
 			of R-URI. It can be a dynamic string with pseudo-variables.
1125 1130
 			</para>
1126 1131
 		</listitem>
1132
+		<listitem>
1133
+			<para>
1134
+			<emphasis>match_option</emphasis> (optional) - flag parameter to restrict
1135
+			contact search. use reg_xavp_cfg to set the values to compare to.
1136
+			</para>
1137
+            <para>flag values is as follows:</para>
1138
+			<itemizedlist>
1139
+				<listitem>
1140
+					<para>1 - match_callid</para>
1141
+				</listiem>
1142
+				<listitem>
1143
+					<para>2 - match_received</para>
1144
+				</listiem>
1145
+				<listitem>
1146
+					<para>4 - match_contact</para>
1147
+				</listiem>
1148
+			</itemizedlist>			
1149
+		</listitem>
1150
+		<listitem>
1151
+			<para>
1152
+			<emphasis>match_action</emphasis> (optional) - actions to perform when match is positive.
1153
+			</para>
1154
+            <para>flag values is as follows:</para>
1155
+			<itemizedlist>
1156
+				<listitem>
1157
+					<para>1 - set xavp_rcd with value from matched contact</para>
1158
+				</listiem>
1159
+			</itemizedlist>						
1160
+		</listitem>
1127 1161
 		</itemizedlist>
1128 1162
 		<para>
1129 1163
 		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
... ...
@@ -1137,6 +1171,13 @@ if (registered("location")) {
1137 1171
 	...
1138 1172
 };
1139 1173
 ...
1174
+$xavp(regcfg=>match_received) = $su;
1175
+if (registered("location","$rz:$Au", 2)) {
1176
+	sl_send_reply("100", "Trying");
1177
+	...
1178
+};
1179
+...
1180
+
1140 1181
 </programlisting>
1141 1182
 		</example>
1142 1183
 	</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 661
 	}
651 662
 
652 663
 	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;
664
+		LM_DBG("searching with match flags (%d,%d)\n", match_flag, reg_match_flag_param);
665
+		if(reg_xavp_cfg.s!=NULL) {
666
+
667
+			if((match_flag & 1)
668
+					&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_callid_name)) != NULL
669
+					&& vavp->val.v.s.len > 0) {
670
+				match_callid = vavp->val.v.s;
671
+				LM_DBG("matching with callid %.*s\n", match_callid.len, match_callid.s);
672
+			}
673
+
674
+			if((match_flag & 2)
675
+					&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_received_name)) != NULL
676
+					&& vavp->val.v.s.len > 0) {
677
+				match_received = vavp->val.v.s;
678
+				LM_DBG("matching with received %.*s\n", match_received.len, match_received.s);
679
+			}
680
+
681
+			if((match_flag & 4)
682
+					&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_contact_name)) != NULL
683
+					&& vavp->val.v.s.len > 0) {
684
+				match_contact = vavp->val.v.s;
685
+				LM_DBG("matching with contact %.*s\n", match_contact.len, match_contact.s);
686
+			}
663 687
 		}
664 688
 
665 689
 		for (ptr = r->contacts; ptr; ptr = ptr->next) {
666 690
 			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))
691
+			if (match_callid.s && /* optionally enforce tighter matching w/ Call-ID */
692
+				match_callid.len > 0 &&
693
+				(match_callid.len != ptr->callid.len || 
694
+				memcmp(match_callid.s, ptr->callid.s, match_callid.len)))
695
+				continue;
696
+			if (match_received.s && /* optionally enforce tighter matching w/ ip:port */
697
+				match_received.len > 0 &&
698
+				(match_received.len != ptr->received.len || 
699
+				memcmp(match_received.s, ptr->received.s, match_received.len)))
669 700
 				continue;
701
+			if (match_contact.s && /* optionally enforce tighter matching w/ Contact */
702
+				match_contact.len > 0 &&
703
+				(match_contact.len != ptr->c.len || 
704
+				memcmp(match_contact.s, ptr->c.s, match_contact.len)))
705
+				continue;
706
+
707
+			if(ptr->xavp!=NULL && match_action_flag == 1) {
708
+				sr_xavp_t *xavp = xavp_clone_level_nodata(ptr->xavp);
709
+				if(xavp_add(xavp, NULL)<0) {
710
+					LM_ERR("error adding xavp for %.*s after successful match\n", aor.len, ZSW(aor.s));
711
+					xavp_destroy_list(&xavp);
712
+				}
713
+			}
714
+
670 715
 			ul.release_urecord(r);
671 716
 			ul.unlock_udomain(_d, &aor);
672 717
 			LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));
718
+
673 719
 			return 1;
674 720
 		}
675 721
 	}
... ...
@@ -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 163
 			REQUEST_ROUTE | FAILURE_ROUTE },
165 164
 	{"registered",   (cmd_function)w_registered,  2,  domain_uri_fixup, 0,
166 165
 			REQUEST_ROUTE | FAILURE_ROUTE },
166
+	{"registered",   (cmd_function)w_registered3, 3,  registered_fixup, 0,
167
+			REQUEST_ROUTE | FAILURE_ROUTE },
168
+	{"registered",   (cmd_function)w_registered4, 4,  registered_fixup, 0,
169
+			REQUEST_ROUTE | FAILURE_ROUTE },
167 170
 	{"add_sock_hdr", (cmd_function)add_sock_hdr,  1,  fixup_str_null, 0,
168 171
 			REQUEST_ROUTE },
169 172
 	{"unregister",   (cmd_function)w_unregister,  2,  unreg_fixup, 0,
... ...
@@ -200,7 +203,6 @@ static param_export_t params[] = {
200 203
 	{"max_expires",        INT_PARAM, &default_registrar_cfg.max_expires			},
201 204
 	{"received_param",     PARAM_STR, &rcv_param           					},
202 205
 	{"received_avp",       PARAM_STRING, &rcv_avp_param       					},
203
-	{"reg_callid_avp",     PARAM_STRING, &reg_callid_avp_param					},
204 206
 	{"max_contacts",       INT_PARAM, &default_registrar_cfg.max_contacts			},
205 207
 	{"retry_after",        INT_PARAM, &default_registrar_cfg.retry_after			},
206 208
 	{"sock_flag",          INT_PARAM, &sock_flag           					},
... ...
@@ -209,7 +211,7 @@ static param_export_t params[] = {
209 211
 	{"use_path",           INT_PARAM, &path_enabled        					},
210 212
 	{"path_mode",          INT_PARAM, &path_mode           					},
211 213
 	{"path_use_received",  INT_PARAM, &path_use_params     					},
212
-        {"path_check_local",   INT_PARAM, &path_check_local                                     },
214
+	{"path_check_local",   INT_PARAM, &path_check_local                                     },
213 215
 	{"xavp_cfg",           PARAM_STR, &reg_xavp_cfg     					},
214 216
 	{"xavp_rcd",           PARAM_STR, &reg_xavp_rcd     					},
215 217
 	{"gruu_enabled",       INT_PARAM, &reg_gruu_enabled    					},
... ...
@@ -306,24 +308,6 @@ static int mod_init(void)
306 308
 		rcv_avp_type = 0;
307 309
 	}
308 310
 
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 311
 	bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
328 312
 	if (!bind_usrloc) {
329 313
 		LM_ERR("can't bind usrloc\n");
... ...
@@ -488,6 +472,46 @@ static int w_registered(struct sip_msg* _m, char* _d, char* _uri)
488 472
 	return registered(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL);
489 473
 }
490 474
 
475
+static int w_registered3(struct sip_msg* _m, char* _d, char* _uri, char* _flags)
476
+{
477
+	str uri = {0};
478
+	int flags = 0;
479
+	if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
480
+	{
481
+		LM_ERR("invalid uri parameter\n");
482
+		return -1;
483
+	}
484
+	if(_flags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_flags, &flags)) < 0)
485
+	{
486
+		LM_ERR("invalid flags parameter\n");
487
+		return -1;
488
+	}
489
+	return registered3(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL, flags);
490
+}
491
+
492
+static int w_registered4(struct sip_msg* _m, char* _d, char* _uri, char* _flags, char* _actionflags)
493
+{
494
+	str uri = {0};
495
+	int flags = 0;
496
+	int actionflags = 0;
497
+	if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
498
+	{
499
+		LM_ERR("invalid uri parameter\n");
500
+		return -1;
501
+	}
502
+	if(_flags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_flags, &flags)) < 0)
503
+	{
504
+		LM_ERR("invalid flags parameter\n");
505
+		return -1;
506
+	}
507
+	if(_actionflags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_actionflags, &actionflags)) < 0)
508
+	{
509
+		LM_ERR("invalid action flag parameter\n");
510
+		return -1;
511
+	}
512
+	return registered4(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL, flags, actionflags);
513
+}
514
+
491 515
 static int w_unregister(struct sip_msg* _m, char* _d, char* _uri)
492 516
 {
493 517
 	str uri = {0};
... ...
@@ -550,6 +574,19 @@ static int domain_uri_fixup(void** param, int param_no)
550 574
 	return 0;
551 575
 }
552 576
 
577
+static int registered_fixup(void** param, int param_no)
578
+{
579
+	if (param_no == 1) {
580
+		return domain_fixup(param, 1);
581
+	} else if (param_no == 2) {
582
+		return fixup_spve_null(param, 1);
583
+	} else if (param_no == 3) {
584
+		return fixup_igp_null(param, 1);
585
+	} else if (param_no == 4) {
586
+		return fixup_igp_null(param, 1);
587
+	}
588
+	return 0;
589
+}
553 590
 
554 591
 /*! \brief
555 592
  * 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;