1 /*
2  * Serial forking functions
3  *
4  * Copyright (C) 2008 Juha Heinanen
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18  * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #include "../../core/qvalue.h"
29 #include "../../core/mem/mem.h"
30 #include "../../core/socket_info.h"
31 #include "../../core/usr_avp.h"
32 #include "../../core/dset.h"
33 #include "../../core/parser/msg_parser.h"
34 #include "../../core/ut.h"
35 #include "../../core/xavp.h"
36 #include "../../core/sr_module.h"
37 #include "../../core/rand/kam_rand.h"
38 #include "config.h"
39 #include "t_funcs.h"
40 #include "t_reply.h"
41 #include "t_lookup.h"
42 
43 /* usr_avp flag for sequential forking */
44 #define Q_FLAG      (1<<2)
45 /* t_load_contacts modes/algorithms */
46 #define T_LOAD_STANDARD     0
47 #define T_LOAD_PROPORTIONAL 1
48 
49 extern str ulattrs_xavp_name;
50 
51 /* Struture where information regarding contacts is stored */
52 struct contact {
53 	str uri;
54 	qvalue_t q;
55 	str dst_uri;
56 	str path;
57 	struct socket_info* sock;
58 	str instance;
59 	str ruid;
60 	str location_ua;
61 	unsigned int flags;
62 	unsigned short q_flag;
63 	struct contact *next;
64 	sr_xavp_t *ulattrs;
65 	unsigned short q_index;
66 };
67 
68 struct instance_list {
69 	str instance;
70 	struct instance_list *next;
71 };
72 
73 /*
74  * Frees contact list used by load_contacts function
75  */
free_contact_list(struct contact * curr)76 static inline void free_contact_list(struct contact *curr) {
77 	struct contact *prev;
78 	while (curr) {
79 		prev = curr;
80 		curr = curr->next;
81 		pkg_free(prev);
82 	}
83 }
84 
85 /*
86  * Frees instance list used by next_contacts function
87  */
free_instance_list(struct instance_list * curr)88 static inline void free_instance_list(struct instance_list *curr) {
89 	struct instance_list *prev;
90 	while (curr) {
91 		pkg_free(curr->instance.s);
92 		prev = curr;
93 		curr = curr->next;
94 		pkg_free(prev);
95 	}
96 }
97 
98 static str uri_name = {"uri", 3};
99 static str dst_uri_name = {"dst_uri", 7};
100 static str path_name = {"path", 4};
101 static str sock_name = {"sock", 4};
102 static str instance_name = {"instance", 8};
103 static str flags_name = {"flags", 5};
104 static str q_flag_name = {"q_flag", 6};
105 static str ruid_name = {"ruid", 4};
106 static str ua_name = {"ua", 2};
107 
add_contacts_avp(str * uri,str * dst_uri,str * path,str * sock_str,unsigned int flags,unsigned int q_flag,str * instance,str * ruid,str * location_ua,sr_xavp_t * ulattrs_xavp,sr_xavp_t ** pxavp)108 void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
109 		unsigned int flags, unsigned int q_flag, str *instance,
110 		str *ruid, str *location_ua, sr_xavp_t *ulattrs_xavp,
111 		sr_xavp_t **pxavp)
112 {
113 	sr_xavp_t *record;
114 	sr_xval_t val;
115 
116 	record = NULL;
117 
118 	val.type = SR_XTYPE_STR;
119 	val.v.s = *uri;
120 	xavp_add_value(&uri_name, &val, &record);
121 
122 	if (dst_uri->len > 0) {
123 		val.type = SR_XTYPE_STR;
124 		val.v.s = *dst_uri;
125 		xavp_add_value(&dst_uri_name, &val, &record);
126 	}
127 
128 	if (path->len > 0) {
129 		val.type = SR_XTYPE_STR;
130 		val.v.s = *path;
131 		xavp_add_value(&path_name, &val, &record);
132 	}
133 
134 	if (sock_str->len > 0) {
135 		val.v.s = *sock_str;
136 		xavp_add_value(&sock_name, &val, &record);
137 	}
138 
139 	val.type = SR_XTYPE_INT;
140 	val.v.i = flags;
141 	xavp_add_value(&flags_name, &val, &record);
142 
143 	val.type = SR_XTYPE_INT;
144 	val.v.i = q_flag;
145 	xavp_add_value(&q_flag_name, &val, &record);
146 
147 	if (instance->len > 0) {
148 		val.type = SR_XTYPE_STR;
149 		val.v.s = *instance;
150 		xavp_add_value(&instance_name, &val, &record);
151 	}
152 
153 	if (ruid->len > 0) {
154 		val.type = SR_XTYPE_STR;
155 		val.v.s = *ruid;
156 		xavp_add_value(&ruid_name, &val, &record);
157 	}
158 
159 	if (location_ua->len > 0) {
160 		val.type = SR_XTYPE_STR;
161 		val.v.s = *location_ua;
162 		xavp_add_value(&ua_name, &val, &record);
163 	}
164 
165 	xavp_add(xavp_clone_level_nodata(ulattrs_xavp), &record);
166 
167 	val.type = SR_XTYPE_XAVP;
168 	val.v.xavp = record;
169 	if(pxavp) {
170 		if((*pxavp = xavp_add_value_after(&contacts_avp, &val, *pxavp))==NULL) {
171 			/* failed to add xavps to the end of the list */
172 			LM_ERR("failed to add xavps to the end of the list\n");
173 			xavp_destroy_list(&record);
174 		}
175 	}
176 	else {
177 		if(xavp_add_value(&contacts_avp, &val, NULL)==NULL) {
178 			/* failed to add xavps to root list */
179 			LM_ERR("failed to add xavps to root list\n");
180 			xavp_destroy_list(&record);
181 		}
182 	}
183 }
184 
185 /*
186  * Socket preparation for 'add_contacts_avp' function
187  */
add_contacts_avp_preparation(struct contact * curr,char * sock_buf,sr_xavp_t ** pxavp)188 int add_contacts_avp_preparation(struct contact *curr, char *sock_buf, sr_xavp_t **pxavp)
189 {
190 	str sock_str;
191 	int len;
192 
193 	if (curr->sock) {
194 		len = MAX_SOCKET_STR - 1;
195 		if (socket2str(sock_buf, &len, curr->sock) < 0) {
196 			LM_ERR("failed to convert socket to str\n");
197 			return -1;
198 		}
199 		sock_buf[len] = 0;
200 		sock_str.s = sock_buf;
201 		sock_str.len = len + 1;
202 	} else {
203 		sock_str.s = 0;
204 		sock_str.len = 0;
205 	}
206 
207 	add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
208 			&sock_str, curr->flags, curr->q_flag,
209 			&(curr->instance), &(curr->ruid), &(curr->location_ua),
210 			curr->ulattrs, pxavp);
211 
212 	return 0;
213 }
214 
215 /*
216  * Loads contacts in destination set into contacts_avp in reverse
217  * priority order and associated each contact with Q_FLAG telling if
218  * contact is the last one in its priority class.
219  */
t_load_contacts_standard(struct contact * contacts,char * sock_buf)220 int t_load_contacts_standard(struct contact *contacts, char *sock_buf)
221 {
222 	struct contact *curr;
223 
224 	/* Assign values for q_flags */
225 	curr = contacts;
226 	curr->q_flag = 0;
227 	while (curr->next) {
228 		if (curr->q < curr->next->q) {
229 			curr->next->q_flag = Q_FLAG;
230 		} else {
231 			curr->next->q_flag = 0;
232 		}
233 		curr = curr->next;
234 	}
235 
236 	/* Add contacts to contacts_avp */
237 	curr = contacts;
238 	while (curr) {
239 		if (add_contacts_avp_preparation(curr, sock_buf, NULL) < 0) {
240 			return -1;
241 		}
242 
243 		curr = curr->next;
244 	}
245 
246 	return 0;
247 }
248 
249 /*
250  * Loads contacts in destination set into contacts_avp in reverse
251  * proportional order. Each contact is associated with Q_FLAG beacuse
252  * only one contact at a time has to ring.
253  */
t_load_contacts_proportional(struct contact * contacts,char * sock_buf,int n,unsigned short q_total)254 int t_load_contacts_proportional(struct contact *contacts, char *sock_buf, int n, unsigned short q_total)
255 {
256 	int q_remove, n_rand, idx;
257 	struct contact *curr;
258 	sr_xavp_t *lxavp = NULL;
259 
260 	/* Add contacts with q-value NOT equals to 0 and NOT negative to contacts_avp */
261 	for (idx = 0; idx < n; idx++) {
262 		q_remove = 0;
263 
264 		/* Generate a random number from 0 to (q_total -1) */
265 		n_rand = kam_rand() % q_total;
266 
267 		curr = contacts;
268 		while (curr) {
269 			if (curr->q <= 0) {
270 				curr = curr->next;
271 				continue;
272 			}
273 
274 			if (q_remove != 0) {
275 				/* ALREADY FOUND */
276 				curr->q_index -= q_remove;
277 			}
278 			else if (curr->q_index > n_rand) {
279 				/* FOUND */
280 				LM_DBG("proportionally selected contact with uri: %s (q: %d, random: %d, q_index: %d, q_total: %d)\n", curr->uri.s, curr->q, n_rand, curr->q_index, q_total);
281 				q_remove = curr->q;
282 				q_total -= q_remove;
283 				curr->q_index -= q_remove;
284 				curr->q_flag = Q_FLAG;
285 
286 				if (add_contacts_avp_preparation(curr, sock_buf, &lxavp) < 0) {
287 					return -1;
288 				}
289 			}
290 
291 			curr = curr->next;
292 		}
293 	}
294 
295 	/* Add contacts with q-value equals to 0 or negative to contacts_avp */
296 	curr = contacts;
297 	while (curr) {
298 		if (curr->q > 0) {
299 			curr = curr->next;
300 			continue;
301 		}
302 
303 		LM_DBG("proportionally added backup contact with uri: %s (q: %d)\n", curr->uri.s, curr->q);
304 		curr->q_flag = Q_FLAG;
305 
306 		if (add_contacts_avp_preparation(curr, sock_buf, &lxavp) < 0) {
307 			return -1;
308 		}
309 
310 		curr = curr->next;
311 	}
312 
313 	return 0;
314 }
315 
316 /*
317  * Loads contacts in destination set and process it. Then call
318  * 't_load_contacts_proportional' or 't_load_contacts_standard'
319  * function based on the selected ordering machanism. Finally,
320  * removes all branches from destination set.
321  */
ki_t_load_contacts_mode(struct sip_msg * msg,int mode)322 int ki_t_load_contacts_mode(struct sip_msg* msg, int mode)
323 {
324 	branch_t *branch;
325 	str *ruri;
326 	struct contact *contacts, *next, *prev, *curr;
327 	int first_idx, idx;
328 	char sock_buf[MAX_SOCKET_STR];
329 	unsigned short q_total = 0;
330 	int n_elements = 0;
331 
332 	/* Check if contacts_avp has been defined */
333 	if (contacts_avp.len == 0) {
334 		LM_ERR("feature has been disabled - "
335 				"to enable define contacts_avp module parameter");
336 		return -1;
337 	}
338 
339 	/* Check if anything needs to be done */
340 	LM_DBG("nr_branches is %d - new uri mode %d\n", nr_branches, ruri_is_new);
341 
342 	if ((nr_branches == 0) || ((nr_branches == 1) && !ruri_is_new)) {
343 		LM_DBG("nothing to do - only one contact!\n");
344 		return 1;
345 	}
346 
347 	/* Allocate memory for first contact */
348 	contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
349 	if (!contacts) {
350 		PKG_MEM_ERROR_FMT("for contact info\n");
351 		return -1;
352 	}
353 	memset(contacts, 0, sizeof(struct contact));
354 
355 	if (ruri_is_new) {
356 		ruri = GET_RURI(msg);
357 		if (!ruri) {
358 			free_contact_list(contacts);
359 			LM_ERR("no Request-URI found\n");
360 			return -1;
361 		}
362 		/* Insert Request-URI branch to first contact */
363 		contacts->uri.s = ruri->s;
364 		contacts->uri.len = ruri->len;
365 		contacts->dst_uri = msg->dst_uri;
366 		contacts->sock = msg->force_send_socket;
367 		getbflagsval(0, &contacts->flags);
368 		contacts->path = msg->path_vec;
369 		contacts->q = get_ruri_q();
370 		contacts->instance = msg->instance;
371 		contacts->ruid = msg->ruid;
372 		contacts->location_ua = msg->location_ua;
373 		if (ulattrs_xavp_name.s != NULL)
374 		{
375 			contacts->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, 0, NULL);
376 		}
377 		first_idx = 0;
378 	} else {
379 		/* Insert first branch to first contact */
380 		branch = get_sip_branch(0);
381 		contacts->uri.s = branch->uri;
382 		contacts->uri.len = branch->len;
383 		contacts->dst_uri.s = branch->dst_uri;
384 		contacts->dst_uri.len = branch->dst_uri_len;
385 		contacts->sock = branch->force_send_socket;
386 		contacts->flags = branch->flags;
387 		contacts->path.s = branch->path;
388 		contacts->path.len = branch->path_len;
389 		contacts->q = branch->q;
390 		contacts->instance.s = branch->instance;
391 		contacts->instance.len = branch->instance_len;
392 		contacts->ruid.s = branch->ruid;
393 		contacts->ruid.len = branch->ruid_len;
394 		contacts->location_ua.s = branch->location_ua;
395 		contacts->location_ua.len = branch->location_ua_len;
396 		if (ulattrs_xavp_name.s != NULL)
397 		{
398 			contacts->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, 1, NULL);
399 		}
400 		first_idx = 1;
401 	}
402 
403 	contacts->q_index = contacts->q;
404 	if (mode == T_LOAD_PROPORTIONAL) {
405 		/* Save in q_index the index to check for the proportional order
406 		   Don't consider elements with Q value 0 or negative */
407 		if (contacts->q > 0) {
408 			q_total += contacts->q;
409 			n_elements += 1;
410 		}
411 		contacts->q_index = q_total;
412 	}
413 
414 	contacts->next = (struct contact *)0;
415 
416 	/* Insert (remaining) branches to contact list in increasing q order */
417 	for (idx = first_idx; (branch = get_sip_branch(idx)) != 0; idx++) {
418 
419 		next = (struct contact *)pkg_malloc(sizeof(struct contact));
420 		if (!next) {
421 			PKG_MEM_ERROR_FMT("for contact info\n");
422 			free_contact_list(contacts);
423 			return -1;
424 		}
425 
426 		memset(next, 0, sizeof(struct contact));
427 		next->uri.s = branch->uri;
428 		next->uri.len = branch->len;
429 		next->dst_uri.s = branch->dst_uri;
430 		next->dst_uri.len = branch->dst_uri_len;
431 		next->sock = branch->force_send_socket;
432 		next->flags = branch->flags;
433 		next->path.s = branch->path;
434 		next->path.len = branch->path_len;
435 		next->q = branch->q;
436 		next->instance.s = branch->instance;
437 		next->instance.len = branch->instance_len;
438 		next->ruid.s = branch->ruid;
439 		next->ruid.len = branch->ruid_len;
440 		next->location_ua.s = branch->location_ua;
441 		next->location_ua.len = branch->location_ua_len;
442 		if (ulattrs_xavp_name.s != NULL)
443 		{
444 			next->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, idx + 1, NULL);
445 		}
446 
447 		next->q_index = next->q;
448 		if (mode == T_LOAD_PROPORTIONAL) {
449 			/* Save in q_index the index to check for the proportional order
450 			   Don't consider elements with Q value 0 or negative */
451 			if (next->q > 0) {
452 				q_total += next->q;
453 				n_elements += 1;
454 			}
455 			next->q_index = q_total;
456 		}
457 
458 		next->next = (struct contact *)0;
459 
460 		prev = (struct contact *)0;
461 		curr = contacts;
462 		if (mode == T_LOAD_PROPORTIONAL) {
463 			while (curr &&
464 					((curr->q_index < next->q_index) ||
465 					 ((curr->q_index == next->q_index) && (next->path.len == 0)))) {
466 				prev = curr;
467 				curr = curr->next;
468 			}
469 		} else {
470 			while (curr &&
471 					((curr->q < next->q) ||
472 					 ((curr->q == next->q) && (next->path.len == 0)))) {
473 				prev = curr;
474 				curr = curr->next;
475 			}
476 		}
477 		if (!curr) {
478 			next->next = (struct contact *)0;
479 			prev->next = next;
480 		} else {
481 			next->next = curr;
482 			if (prev) {
483 				prev->next = next;
484 			} else {
485 				contacts = next;
486 			}
487 		}
488 	}
489 
490 	if (mode == T_LOAD_PROPORTIONAL) {
491 		if (t_load_contacts_proportional(contacts, sock_buf, n_elements, q_total) < 0) {
492 			free_contact_list(contacts);
493 			return -1;
494 		}
495 	}
496 	else {
497 		if (t_load_contacts_standard(contacts, sock_buf) < 0) {
498 			free_contact_list(contacts);
499 			return -1;
500 		}
501 	}
502 
503 	/* Clear all branches */
504 	clear_branches();
505 	if (ulattrs_xavp_name.s != NULL){
506 		xavp_rm_by_name(&ulattrs_xavp_name, 1, NULL);
507 	}
508 
509 	/* Free contact list */
510 	free_contact_list(contacts);
511 
512 	return 1;
513 }
514 
ki_t_load_contacts(struct sip_msg * msg)515 int ki_t_load_contacts(struct sip_msg* msg)
516 {
517 	return ki_t_load_contacts_mode(msg, T_LOAD_STANDARD);
518 }
519 
t_load_contacts(struct sip_msg * msg,char * mode,char * value)520 int t_load_contacts(struct sip_msg* msg, char* mode, char* value)
521 {
522 	int i = T_LOAD_STANDARD;
523 
524 	if(mode) {
525 		if(get_int_fparam(&i, msg, (fparam_t*)mode)<0) return -1;
526 
527 		if ((i != T_LOAD_STANDARD) && (i != T_LOAD_PROPORTIONAL)) {
528 			LM_ERR("invalid load_contact mode: %d, please use 0 (standard) or 1 (proportional)\n", i);
529 			return -1;
530 		}
531 		LM_DBG("load_contact mode selected: %d\n", i);
532 	}
533 	else
534 	{
535 		LM_DBG("load_contact mode not selected, using: %d\n", T_LOAD_STANDARD);
536 	}
537 
538 	return ki_t_load_contacts_mode(msg, i);
539 }
540 
add_contact_flows_avp(str * uri,str * dst_uri,str * path,str * sock_str,unsigned int flags,str * instance,str * ruid,str * location_ua,sr_xavp_t * ulattrs_xavp)541 void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
542 		unsigned int flags, str *instance, str *ruid,
543 		str *location_ua, sr_xavp_t *ulattrs_xavp)
544 {
545 	sr_xavp_t *record;
546 	sr_xval_t val;
547 
548 	record = NULL;
549 
550 	val.type = SR_XTYPE_STR;
551 	val.v.s = *uri;
552 	xavp_add_value(&uri_name, &val, &record);
553 
554 	if (dst_uri->len > 0) {
555 		val.type = SR_XTYPE_STR;
556 		val.v.s = *dst_uri;
557 		xavp_add_value(&dst_uri_name, &val, &record);
558 	}
559 
560 	if (path->len > 0) {
561 		val.type = SR_XTYPE_STR;
562 		val.v.s = *path;
563 		xavp_add_value(&path_name, &val, &record);
564 	}
565 
566 	if (sock_str->len > 0) {
567 		val.v.s = *sock_str;
568 		xavp_add_value(&sock_name, &val, &record);
569 	}
570 
571 	if (instance->len > 0) {
572 		val.type = SR_XTYPE_STR;
573 		val.v.s = *instance;
574 		xavp_add_value(&instance_name, &val, &record);
575 	}
576 
577 	if (ruid->len > 0) {
578 		val.type = SR_XTYPE_STR;
579 		val.v.s = *ruid;
580 		xavp_add_value(&ruid_name, &val, &record);
581 	}
582 
583 	if (location_ua->len > 0) {
584 		val.type = SR_XTYPE_STR;
585 		val.v.s = *location_ua;
586 		xavp_add_value(&ua_name, &val, &record);
587 	}
588 
589 	xavp_add(ulattrs_xavp, &record);
590 
591 	val.type = SR_XTYPE_INT;
592 	val.v.i = flags;
593 	xavp_add_value(&flags_name, &val, &record);
594 
595 	val.type = SR_XTYPE_XAVP;
596 	val.v.xavp = record;
597 	if(xavp_add_value(&contact_flows_avp, &val, NULL)==NULL) {
598 		/* failed to add xavps to root list */
599 		LM_ERR("failed to add xavps to root list\n");
600 		xavp_destroy_list(&record);
601 	}
602 }
603 
604 /*
605  * Adds to request a new destination set that includes highest
606  * priority class contacts in contacts_avp, but only one contact with same
607  * +sip.instance value is included.  Others are added to contact_flows_avp
608  * for later consumption by next_contact_flow().
609  * Request URI is rewritten with first contact and the remaining contacts
610  * (if any) are added as branches. Removes all highest priority contacts
611  * from contacts_avp.
612  * Returns 1, if contacts_avp was not empty and a destination set was
613  * successfully added.  Returns -2, if contacts_avp was empty and thus
614  * there was nothing to do. Returns -1 in case of an error. */
ki_t_next_contacts(struct sip_msg * msg)615 int ki_t_next_contacts(struct sip_msg* msg)
616 {
617 	str uri, dst_uri, path, instance, host, sock_str, ruid, location_ua;
618 	struct socket_info *sock;
619 	unsigned int flags, q_flag;
620 	sr_xavp_t *xavp_list, *xavp, *prev_xavp, *vavp;
621 	int port, proto;
622 	struct instance_list *il, *ilp;
623 
624 	/* Check if contacts_avp has been defined */
625 	if (contacts_avp.len == 0) {
626 		LM_ERR("feature has been disabled - "
627 				"to enable define contacts_avp module parameter");
628 		return -1;
629 	}
630 
631 	/* Load Request-URI and branches */
632 
633 	/* Find first contacts_avp value */
634 	xavp_list = xavp_get(&contacts_avp, NULL);
635 	if (!xavp_list) {
636 		LM_DBG("no contacts in contacts_avp - we are done!\n");
637 		return -2;
638 	}
639 
640 	xavp = xavp_list;
641 
642 	vavp = xavp_get(&uri_name, xavp->val.v.xavp);
643 	uri = vavp->val.v.s;
644 
645 	vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
646 	if (vavp != NULL) {
647 		dst_uri = vavp->val.v.s;
648 	} else {
649 		dst_uri.s = 0;
650 		dst_uri.len = 0;
651 	}
652 
653 	vavp = xavp_get(&path_name, xavp->val.v.xavp);
654 	if (vavp != NULL) {
655 		path = vavp->val.v.s;
656 	} else {
657 		path.s = 0;
658 		path.len = 0;
659 	}
660 
661 	vavp = xavp_get(&sock_name, xavp->val.v.xavp);
662 	if (vavp != NULL) {
663 		sock_str.s = vavp->val.v.s.s;
664 		if (parse_phostport(sock_str.s, &host.s, &host.len, &port, &proto)
665 				!= 0) {
666 			LM_ERR("parsing of socket info <%s> failed\n", sock_str.s);
667 			xavp_rm(xavp_list, NULL);
668 			return -1;
669 		}
670 		sock = grep_sock_info(&host, (unsigned short)port,
671 				(unsigned short)proto);
672 		if (sock == 0) {
673 			xavp_rm(xavp_list, NULL);
674 			return -1;
675 		}
676 	} else {
677 		sock = NULL;
678 	}
679 
680 	vavp = xavp_get(&flags_name, xavp->val.v.xavp);
681 	flags = vavp->val.v.i;
682 
683 	vavp = xavp_get(&q_flag_name, xavp->val.v.xavp);
684 	q_flag = vavp->val.v.i;
685 
686 	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
687 	il = (struct instance_list *)0;
688 	if ((vavp != NULL) && !q_flag) {
689 		instance = vavp->val.v.s;
690 		il = (struct instance_list *)pkg_malloc(sizeof(struct instance_list));
691 		if (!il) {
692 			PKG_MEM_ERROR_FMT("for instance list entry\n");
693 			return -1;
694 		}
695 		il->instance.s = pkg_malloc(instance.len);
696 		if (!il->instance.s) {
697 			pkg_free(il);
698 			PKG_MEM_ERROR_FMT("for instance list instance\n");
699 			return -1;
700 		}
701 		il->instance.len = instance.len;
702 		memcpy(il->instance.s, instance.s, instance.len);
703 		il->next = (struct instance_list *)0;
704 		set_instance(msg, &instance);
705 	} else {
706 		instance.s = 0;
707 		instance.len = 0;
708 	}
709 
710 	vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
711 	if (vavp != NULL) {
712 		ruid = vavp->val.v.s;
713 	} else {
714 		ruid.s = 0;
715 		ruid.len = 0;
716 	}
717 	vavp = xavp_get(&ua_name, xavp->val.v.xavp);
718 	if (vavp != NULL) {
719 		location_ua = vavp->val.v.s;
720 	} else {
721 		location_ua.s = 0;
722 		location_ua.len = 0;
723 	}
724 
725 	if (ulattrs_xavp_name.s != NULL)
726 	{
727 		vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
728 		xavp_insert(vavp, 0, NULL);
729 	}
730 
731 	/* Rewrite Request-URI */
732 	if(rewrite_uri(msg, &uri)<0) {
733 		LM_WARN("failed to rewrite r-uri\n");
734 	}
735 
736 	if (dst_uri.len) {
737 		if(set_dst_uri(msg, &dst_uri)<0) {
738 			LM_ERR("failed to set dst uri\n");
739 		}
740 	} else {
741 		reset_dst_uri(msg);
742 	}
743 
744 	if (path.len) {
745 		if(set_path_vector(msg, &path)<0) {
746 			LM_WARN("failed to set path vector\n");
747 		}
748 	} else {
749 		reset_path_vector(msg);
750 	}
751 
752 	set_force_socket(msg, sock);
753 
754 	setbflagsval(0, flags);
755 
756 	set_ruid(msg, &ruid);
757 
758 	set_ua(msg, &location_ua);
759 
760 	/* Check if there was only one contact at this priority */
761 	if (q_flag) {
762 		xavp_rm(xavp, NULL);
763 		return 1;
764 	}
765 
766 	/* Append branches until out of branches or Q_FLAG is set */
767 	/* If a branch has same instance value as some previous branch, */
768 	/* instead of appending it, add it to contact_flows_avp */
769 
770 	xavp_rm_by_name(&contact_flows_avp, 1, NULL);
771 	prev_xavp = xavp;
772 
773 	while ((xavp = xavp_get_next(prev_xavp)) != NULL) {
774 
775 		xavp_rm(prev_xavp, NULL);
776 
777 		vavp = xavp_get(&q_flag_name, xavp->val.v.xavp);
778 		if(vavp) {
779 			q_flag = vavp->val.v.i;
780 		} else {
781 			q_flag = 0;
782 		}
783 
784 		vavp = xavp_get(&uri_name, xavp->val.v.xavp);
785 		if(vavp) {
786 			uri = vavp->val.v.s;
787 		} else {
788 			uri.len = 0;
789 		}
790 
791 		vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
792 		if (vavp != NULL) {
793 			dst_uri = vavp->val.v.s;
794 		} else {
795 			dst_uri.len = 0;
796 		}
797 
798 		vavp = xavp_get(&path_name, xavp->val.v.xavp);
799 		if (vavp != NULL) {
800 			path = vavp->val.v.s;
801 		} else {
802 			path.len = 0;
803 		}
804 
805 		vavp = xavp_get(&sock_name, xavp->val.v.xavp);
806 		if (vavp != NULL) {
807 			sock_str = vavp->val.v.s;
808 			if (parse_phostport(sock_str.s, &host.s, &host.len, &port, &proto)
809 					!= 0) {
810 				LM_ERR("parsing of socket info <%s> failed\n", sock_str.s);
811 				free_instance_list(il);
812 				xavp_rm(xavp_list, NULL);
813 				return -1;
814 			}
815 			sock = grep_sock_info(&host, (unsigned short)port,
816 					(unsigned short)proto);
817 			if (sock == 0) {
818 				free_instance_list(il);
819 				xavp_rm(xavp_list, NULL);
820 				return -1;
821 			}
822 		} else {
823 			sock = NULL;
824 			sock_str.s = 0;
825 			sock_str.len = 0;
826 		}
827 
828 		vavp = xavp_get(&flags_name, xavp->val.v.xavp);
829 		if (vavp != NULL) {
830 			flags = vavp->val.v.i;
831 		} else {
832 			flags = 0;
833 		}
834 
835 		vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
836 		if (vavp != NULL) {
837 			ruid = vavp->val.v.s;
838 		} else {
839 			ruid.s = 0;
840 			ruid.len = 0;
841 		}
842 
843 		vavp = xavp_get(&ua_name, xavp->val.v.xavp);
844 		if (vavp != NULL) {
845 			location_ua = vavp->val.v.s;
846 		} else {
847 			location_ua.s = 0;
848 			location_ua.len = 0;
849 		}
850 
851 		vavp = xavp_get(&instance_name, xavp->val.v.xavp);
852 		if (vavp != NULL) {
853 			instance = vavp->val.v.s;
854 			ilp = il;
855 			while (ilp) {
856 				if ((instance.len == ilp->instance.len) &&
857 						(strncmp(instance.s, ilp->instance.s, instance.len) == 0))
858 					break;
859 				ilp = ilp->next;
860 			}
861 			if (ilp) {
862 				vavp = (ulattrs_xavp_name.s != NULL)?xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp):NULL;
863 				add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
864 						flags, &instance, &ruid, &location_ua, vavp);
865 				goto check_q_flag;
866 			}
867 			if (!q_flag) {
868 				ilp = (struct instance_list *)
869 					pkg_malloc(sizeof(struct instance_list));
870 				if (!ilp) {
871 					PKG_MEM_ERROR_FMT("for instance list element\n");
872 					free_instance_list(il);
873 					return -1;
874 				}
875 				ilp->instance.s = pkg_malloc(instance.len);
876 				if (!ilp->instance.s) {
877 					PKG_MEM_ERROR_FMT("for instance list instance\n");
878 					pkg_free(ilp);
879 					free_instance_list(il);
880 					return -1;
881 				}
882 				ilp->instance.len = instance.len;
883 				memcpy(ilp->instance.s, instance.s, instance.len);
884 				ilp->next = il;
885 				il = ilp;
886 			}
887 		} else {
888 			instance.s = 0;
889 			instance.len = 0;
890 		}
891 
892 		LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s' inst-'%.*s'"
893 				" ruid-'%.*s' location_ua-'%.*s'\n",
894 				uri.len, uri.s,
895 				dst_uri.len, (dst_uri.len > 0)?dst_uri.s:"",
896 				path.len, (path.len>0)?path.s:"",
897 				instance.len, (instance.len>0)?instance.s:"",
898 				ruid.len, (ruid.len>0)?ruid.s:"",
899 				location_ua.len, (location_ua.len>0)?location_ua.s:"");
900 		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
901 					&ruid, &location_ua) != 1) {
902 			LM_ERR("appending branch failed\n");
903 			free_instance_list(il);
904 			xavp_rm(xavp_list, NULL);
905 			return -1;
906 		}
907 
908 		if (ulattrs_xavp_name.s != NULL)
909 		{
910 			vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
911 			xavp_insert(vavp, nr_branches, NULL);
912 		}
913 
914 check_q_flag:
915 		if (q_flag) {
916 			free_instance_list(il);
917 			xavp_rm(xavp, NULL);
918 			return 1;
919 		}
920 
921 		prev_xavp = xavp;
922 	}
923 
924 	free_instance_list(il);
925 	xavp_rm(prev_xavp, NULL);
926 
927 	return 1;
928 }
929 
t_next_contacts(struct sip_msg * msg,char * key,char * value)930 int t_next_contacts(struct sip_msg* msg, char* key, char* value)
931 {
932 	return ki_t_next_contacts(msg);
933 }
934 
935 /*
936  * Adds to request a new destination set that includes contacts
937  * from contact_flows_avp.  Only one contact with same +sip.instance
938  * value is included.
939  * Request URI is rewritten with first contact and the remaining contacts
940  * (if any) are added as branches. Removes all used contacts
941  * from contacts_avp.
942  * Returns 1, if contact_flows_avp was not empty and a destination set was
943  * successfully added.  Returns -2, if contact_flows_avp was empty and thus
944  * there was nothing to do. Returns -1 in case of an error. */
ki_t_next_contact_flow(struct sip_msg * msg)945 int ki_t_next_contact_flow(struct sip_msg* msg)
946 {
947 	str uri, dst_uri, path, instance, host, ruid, location_ua;
948 	str this_instance;
949 	struct socket_info *sock;
950 	unsigned int flags;
951 	sr_xavp_t *xavp_list, *xavp, *next_xavp, *vavp;
952 	char *tmp;
953 	int port, proto;
954 
955 	/* Check if contact_flows_avp has been defined */
956 	if (contact_flows_avp.len == 0) {
957 		LM_ERR("feature has been disabled - "
958 				"to enable define contact_flows_avp module parameter");
959 		return -1;
960 	}
961 
962 	/* Load Request-URI and branches */
963 	t_get_this_branch_instance(msg, &this_instance);
964 
965 	if (this_instance.len == 0) {
966 		LM_DBG("No instance on this branch\n");
967 		return -2;
968 	}
969 	/* Find first contact_flows_avp value */
970 	xavp_list = xavp_get(&contact_flows_avp, NULL);
971 	if (!xavp_list) {
972 		LM_DBG("no contacts in contact_flows_avp - we are done!\n");
973 		return -2;
974 	}
975 
976 	xavp = xavp_list;
977 
978 	while (xavp) {
979 		next_xavp = xavp_get_next(xavp);
980 
981 		vavp = xavp_get(&instance_name, xavp->val.v.xavp);
982 		if (vavp == NULL) {
983 			/* Does not match this instance */
984 			goto next_xavp;
985 		} else {
986 			instance = vavp->val.v.s;
987 			if ((instance.len != this_instance.len) ||
988 					(strncmp(instance.s, this_instance.s, instance.len) != 0))
989 				/* Does not match this instance */
990 				goto next_xavp;
991 		}
992 
993 		vavp = xavp_get(&uri_name, xavp->val.v.xavp);
994 		if (vavp == NULL) {
995 			goto next_xavp;
996 		} else {
997 			uri = vavp->val.v.s;
998 		}
999 
1000 		vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
1001 		if (vavp != NULL) {
1002 			dst_uri = vavp->val.v.s;
1003 		} else {
1004 			dst_uri.len = 0;
1005 		}
1006 
1007 		vavp = xavp_get(&path_name, xavp->val.v.xavp);
1008 		if (vavp != NULL) {
1009 			path = vavp->val.v.s;
1010 		} else {
1011 			path.len = 0;
1012 		}
1013 
1014 		vavp = xavp_get(&sock_name, xavp->val.v.xavp);
1015 		if (vavp != NULL) {
1016 			tmp = vavp->val.v.s.s;
1017 			if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
1018 				LM_ERR("parsing of socket info <%s> failed\n", tmp);
1019 				xavp_rm(xavp, NULL);
1020 				return -1;
1021 			}
1022 			sock = grep_sock_info(&host, (unsigned short)port,
1023 					(unsigned short)proto);
1024 			if (sock == 0) {
1025 				xavp_rm(xavp, NULL);
1026 				return -1;
1027 			}
1028 		} else {
1029 			sock = NULL;
1030 		}
1031 
1032 		vavp = xavp_get(&flags_name, xavp->val.v.xavp);
1033 		if (vavp != NULL) {
1034 			flags = vavp->val.v.i;
1035 		} else {
1036 			flags = 0;
1037 		}
1038 
1039 		vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
1040 		if (vavp != NULL) {
1041 			ruid = vavp->val.v.s;
1042 		} else {
1043 			ruid.s = "";
1044 			ruid.len = 0;
1045 		}
1046 
1047 		vavp = xavp_get(&ua_name, xavp->val.v.xavp);
1048 		if (vavp != NULL) {
1049 			location_ua = vavp->val.v.s;
1050 		} else {
1051 			location_ua.s = "";
1052 			location_ua.len = 0;
1053 		}
1054 
1055 		LM_DBG("Appending branch uri-'%.*s' dst-'%.*s' path-'%.*s'"
1056 				" inst-'%.*s' ruid-'%.*s' location_ua-'%.*s'\n",
1057 				uri.len, uri.s,
1058 				dst_uri.len, (dst_uri.len > 0)?dst_uri.s:"",
1059 				path.len, (path.len>0)?path.s:"",
1060 				instance.len, (instance.len>0)?instance.s:"",
1061 				ruid.len, ruid.s, location_ua.len, location_ua.s);
1062 		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
1063 					&ruid, &location_ua) != 1) {
1064 			LM_ERR("appending branch failed\n");
1065 			xavp_rm(xavp_list, NULL);
1066 			return -1;
1067 		}
1068 
1069 		if (ulattrs_xavp_name.s != NULL)
1070 		{
1071 			vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
1072 			xavp_insert(vavp, nr_branches, NULL);
1073 		}
1074 
1075 		xavp_rm(xavp, NULL);
1076 		return 1;
1077 next_xavp:
1078 		xavp = next_xavp;
1079 	}
1080 
1081 	return -1;
1082 }
1083 
t_next_contact_flow(struct sip_msg * msg,char * key,char * value)1084 int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
1085 {
1086 	return ki_t_next_contact_flow(msg);
1087 }
1088