1 /*
2  * destination set
3  *
4  * Copyright (C) 2001-2004 FhG FOKUS
5  *
6  * This file is part of Kamailio, a free SIP server.
7  *
8  * Kamailio is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * Kamailio is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 /** Kamailio core :: destination set / branches support.
24  * @file dset.c
25  * @ingroup core
26  * Module: @ref core
27  */
28 
29 #include <string.h>
30 #include "dprint.h"
31 #include "config.h"
32 #include "parser/parser_f.h"
33 #include "parser/parse_uri.h"
34 #include "parser/msg_parser.h"
35 #include "globals.h"
36 #include "ut.h"
37 #include "hash_func.h"
38 #include "error.h"
39 #include "dset.h"
40 #include "mem/mem.h"
41 #include "ip_addr.h"
42 #include "strutils.h"
43 
44 #define CONTACT "Contact: "
45 #define CONTACT_LEN (sizeof(CONTACT) - 1)
46 
47 #define CONTACT_DELIM ", "
48 #define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
49 
50 #define Q_PARAM ";q="
51 #define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
52 
53 #define ROUTE_PARAM "?Route="
54 #define ROUTE_PARAM_LEN (sizeof(ROUTE_PARAM) - 1)
55 
56 #define FLAGS_PARAM ";flags="
57 #define FLAGS_PARAM_LEN (sizeof(FLAGS_PARAM) - 1)
58 
59 /*
60  * Where we store URIs of additional transaction branches
61  * (sr_dst_max_branches - 1 : because of the default branch for r-uri, #0 in tm)
62  */
63 static struct branch *branches = NULL;
64 
65 /* how many of them we have */
66 unsigned int nr_branches = 0;
67 
68 /* branch iterator */
69 static int branch_iterator = 0;
70 
71 /* used to mark ruris "consumed" when branching (1 new, 0 consumed) */
72 int ruri_is_new = 0;
73 
74 /* The q parameter of the Request-URI */
75 static qvalue_t ruri_q = Q_UNSPECIFIED;
76 
77 /* Branch flags of the Request-URI */
78 static flag_t ruri_bflags;
79 
80 
init_dst_set(void)81 int init_dst_set(void)
82 {
83 	if(sr_dst_max_branches<=0 || sr_dst_max_branches>=MAX_BRANCHES_LIMIT) {
84 		LM_ERR("invalid value for max branches parameter: %u\n",
85 				sr_dst_max_branches);
86 		return -1;
87 	}
88 	/* sr_dst_max_branches - 1 : because of the default branch for r-uri, #0 in tm */
89 	branches = (branch_t*)pkg_malloc((sr_dst_max_branches-1)*sizeof(branch_t));
90 	if(branches==NULL) {
91 		PKG_MEM_ERROR;
92 		return -1;
93 	}
94 	memset(branches, 0, (sr_dst_max_branches-1)*sizeof(branch_t));
95 	return 0;
96 }
97 
98 /*! \brief
99  * Return pointer to branch[idx] structure
100  * @param idx - branch index
101  *
102  * @return  pointer to branch or NULL if invalid branch
103  */
get_sip_branch(int idx)104 branch_t *get_sip_branch(int idx)
105 {
106 	if(nr_branches==0)
107 		return NULL;
108 	if(idx<0)
109 	{
110 		if((int)nr_branches + idx >= 0)
111 			return &branches[nr_branches+idx];
112 		return NULL;
113 	}
114 	if(idx < nr_branches)
115 		return &branches[idx];
116 	return 0;
117 }
118 
119 /*! \brief
120  * Drop branch[idx]
121  * @param idx - branch index
122  *
123  * @return  0 on success, -1 on error
124  */
drop_sip_branch(int idx)125 int drop_sip_branch(int idx)
126 {
127 	if(nr_branches==0 || idx>=nr_branches)
128 		return 0;
129 	if(idx<0 && (int)nr_branches+idx<0)
130 		return 0;
131 	if(idx<0)
132 		idx += nr_branches;
133 	/* last branch */
134 	if(idx==nr_branches-1)
135 	{
136 		nr_branches--;
137 		return 0;
138 	}
139 	/* shift back one position */
140 	for(; idx<nr_branches-1; idx++)
141 		memcpy(&branches[idx], &branches[idx+1], sizeof(branch_t));
142 	nr_branches--;
143 	return 0;
144 }
145 
get_bflags_ptr(unsigned int branch)146 static inline flag_t* get_bflags_ptr(unsigned int branch)
147 {
148 	if (branch == 0) return &ruri_bflags;
149 	if (branch - 1 < nr_branches) return &branches[branch - 1].flags;
150 	return NULL;
151 }
152 
153 
setbflag(unsigned int branch,flag_t flag)154 int setbflag(unsigned int branch, flag_t flag)
155 {
156 	flag_t* flags;
157 
158 	if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
159 	(*flags) |= 1 << flag;
160 	return 1;
161 }
162 
163 
isbflagset(unsigned int branch,flag_t flag)164 int isbflagset(unsigned int branch, flag_t flag)
165 {
166 	flag_t* flags;
167 
168 	if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
169 	return ((*flags) & (1 << flag)) ? 1 : -1;
170 }
171 
172 
resetbflag(unsigned int branch,flag_t flag)173 int resetbflag(unsigned int branch, flag_t flag)
174 {
175 	flag_t* flags;
176 
177 	if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
178 	(*flags) &= ~ (1 << flag);
179 	return 1;
180 }
181 
182 
getbflagsval(unsigned int branch,flag_t * res)183 int getbflagsval(unsigned int branch, flag_t* res)
184 {
185 	flag_t* flags;
186 	if (res == NULL) return -1;
187 	if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
188 	*res = *flags;
189 	return 1;
190 }
191 
192 
setbflagsval(unsigned int branch,flag_t val)193 int setbflagsval(unsigned int branch, flag_t val)
194 {
195 	flag_t* flags;
196 	if ((flags = get_bflags_ptr(branch)) == NULL) return -1;
197 	*flags = val;
198 	return 1;
199 }
200 
201 
202 /*
203  * Initialize the branch iterator, the next
204  * call to next_branch will return the first
205  * contact from the dset array
206  */
init_branch_iterator(void)207 void init_branch_iterator(void)
208 {
209 	branch_iterator = 0;
210 }
211 
212 /**
213  * return the value of current branch iterator
214  */
get_branch_iterator(void)215 int get_branch_iterator(void)
216 {
217 	return branch_iterator;
218 }
219 
220 /**
221  * set the value of current branch interator
222  */
set_branch_iterator(int n)223 void set_branch_iterator(int n)
224 {
225 	branch_iterator = n;
226 }
227 
228 
229 /** \brief Get a branch from the destination set
230  * \return Return the 'i' branch from the dset
231  * array, 0 is returned if there are no
232  * more branches
233  */
get_branch(unsigned int i,int * len,qvalue_t * q,str * dst_uri,str * path,unsigned int * flags,struct socket_info ** force_socket,str * ruid,str * instance,str * location_ua)234 char* get_branch(unsigned int i, int* len, qvalue_t* q, str* dst_uri,
235 		str* path, unsigned int *flags,
236 		struct socket_info** force_socket,
237 		str *ruid, str *instance, str *location_ua)
238 {
239 	if (i < nr_branches) {
240 		*len = branches[i].len;
241 		*q = branches[i].q;
242 		if (dst_uri) {
243 			dst_uri->len = branches[i].dst_uri_len;
244 			dst_uri->s = (dst_uri->len)?branches[i].dst_uri:0;
245 		}
246 		if (path) {
247 			path->len = branches[i].path_len;
248 			path->s = (path->len)?branches[i].path:0;
249 		}
250 		if (force_socket)
251 			*force_socket = branches[i].force_send_socket;
252 		if (flags)
253 			*flags = branches[i].flags;
254 		if (ruid) {
255 			ruid->len = branches[i].ruid_len;
256 			ruid->s = (ruid->len)?branches[i].ruid:0;
257 		}
258 		if (instance) {
259 			instance->len = branches[i].instance_len;
260 			instance->s = (instance->len)?branches[i].instance:0;
261 		}
262 		if (location_ua) {
263 			location_ua->len = branches[i].location_ua_len;
264 			location_ua->s
265 				= (location_ua->len)?branches[i].location_ua:0;
266 		}
267 		return branches[i].uri;
268 	} else {
269 		*len = 0;
270 		*q = Q_UNSPECIFIED;
271 		if (dst_uri) {
272 			dst_uri->s = 0;
273 			dst_uri->len = 0;
274 		}
275 		if (path) {
276 			path->s = 0;
277 			path->len = 0;
278 		}
279 		if (force_socket)
280 			*force_socket = 0;
281 		if (flags)
282 			*flags = 0;
283 		if (ruid) {
284 			ruid->s = 0;
285 			ruid->len = 0;
286 		}
287 		if (instance) {
288 			instance->s = 0;
289 			instance->len = 0;
290 		}
291 		if (location_ua) {
292 			location_ua->s = 0;
293 			location_ua->len = 0;
294 		}
295 		return 0;
296 	}
297 }
298 
299 
300 
301 /** Return the next branch from the dset array.
302  * 0 is returned if there are no more branches
303  */
next_branch(int * len,qvalue_t * q,str * dst_uri,str * path,unsigned int * flags,struct socket_info ** force_socket,str * ruid,str * instance,str * location_ua)304 char* next_branch(int* len, qvalue_t* q, str* dst_uri, str* path,
305 		unsigned int* flags, struct socket_info** force_socket,
306 		str* ruid, str *instance, str *location_ua)
307 {
308 	char* ret;
309 
310 	ret=get_branch(branch_iterator, len, q, dst_uri, path, flags,
311 			force_socket, ruid, instance, location_ua);
312 	if (likely(ret))
313 		branch_iterator++;
314 	return ret;
315 }
316 
317 /**
318  * Link branch attributes in the data structure
319  * - return: -1 (<0) on error; 0 - on no valid branch; 1 - on a valid branch
320  */
get_branch_data(unsigned int i,branch_data_t * vbranch)321 int get_branch_data(unsigned int i, branch_data_t *vbranch)
322 {
323 	if(vbranch==NULL) {
324 		return -1;
325 	}
326 	memset(vbranch, 0, sizeof(branch_data_t));
327 
328 	if (i < nr_branches) {
329 		vbranch->uri.s = branches[i].uri;
330 		vbranch->uri.len = branches[i].len;
331 		vbranch->q = branches[i].q;
332 		if (branches[i].dst_uri_len > 0) {
333 			vbranch->dst_uri.len = branches[i].dst_uri_len;
334 			vbranch->dst_uri.s = branches[i].dst_uri;
335 		}
336 		if (branches[i].path_len > 0) {
337 			vbranch->path.len = branches[i].path_len;
338 			vbranch->path.s = branches[i].path;
339 		}
340 		vbranch->force_socket = branches[i].force_send_socket;
341 		vbranch->flags = branches[i].flags;
342 		if (branches[i].ruid_len > 0) {
343 			vbranch->ruid.len = branches[i].ruid_len;
344 			vbranch->ruid.s = branches[i].ruid;
345 		}
346 		if (branches[i].instance_len > 0) {
347 			vbranch->instance.len = branches[i].instance_len;
348 			vbranch->instance.s =branches[i].instance;
349 		}
350 		if (branches[i].location_ua_len > 0) {
351 			vbranch->location_ua.len = branches[i].location_ua_len;
352 			vbranch->location_ua.s = branches[i].location_ua;
353 		}
354 		vbranch->otcpid = branches[i].otcpid;
355 		return 1;
356 	} else {
357 		vbranch->q = Q_UNSPECIFIED;
358 		return 0;
359 	}
360 }
361 
362 /**
363  * Link branch attributes in the data structure and advance the iterator on
364  * return of a valid branch
365  * - return: -1 (<0) on error; 0 - on no valid branch; 1 - on a valid branch
366  */
next_branch_data(branch_data_t * vbranch)367 int next_branch_data(branch_data_t *vbranch)
368 {
369 	int ret;
370 	ret= get_branch_data(branch_iterator, vbranch);
371 	if (ret <= 0) {
372 		return ret;
373 	}
374 	branch_iterator++;
375 	return ret;
376 }
377 
378 /*
379  * Empty the dset array
380  */
clear_branches(void)381 void clear_branches(void)
382 {
383 	nr_branches = 0;
384 	ruri_q = Q_UNSPECIFIED;
385 	ruri_bflags = 0;
386 	ruri_mark_consumed();
387 }
388 
389 
390 
391 /**  Add a new branch to the current destination set.
392  * @param msg sip message, used for getting the uri if not specified (0).
393  * @param uri uri, can be 0 (in which case the uri is taken from msg)
394  * @param dst_uri destination uri, can be 0.
395  * @param path path vector (passed in a string), can be 0.
396  * @param q  q value.
397  * @param flags per branch flags.
398  * @param force_socket socket that should be used when sending.
399  * @param instance sip instance contact header param value
400  * @param reg_id reg-id contact header param value
401  * @param ruid ruid value from usrloc
402  * @param location_ua location user agent
403  *
404  * @return  <0 (-1) on failure, 1 on success (script convention).
405  */
append_branch(struct sip_msg * msg,str * uri,str * dst_uri,str * path,qvalue_t q,unsigned int flags,struct socket_info * force_socket,str * instance,unsigned int reg_id,str * ruid,str * location_ua)406 int append_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
407 		  qvalue_t q, unsigned int flags,
408 		  struct socket_info* force_socket,
409 		  str* instance, unsigned int reg_id,
410 		  str* ruid, str* location_ua)
411 {
412 	str luri;
413 
414 	/* if we have already set up the maximum number
415 	 * of branches, don't try new ones
416 	 */
417 	if (unlikely(nr_branches == sr_dst_max_branches - 1)) {
418 		LM_ERR("max nr of branches exceeded\n");
419 		ser_error = E_TOO_MANY_BRANCHES;
420 		return -1;
421 	}
422 
423 	/* if not parameterized, take current uri */
424 	if (uri==0 || uri->len==0 || uri->s==0) {
425 		if(msg==NULL) {
426 			LM_ERR("no new uri and no msg to take r-uri\n");
427 			ser_error = E_INVALID_PARAMS;
428 			return -1;
429 		}
430 		if (msg->new_uri.s)
431 			luri = msg->new_uri;
432 		else
433 			luri = msg->first_line.u.request.uri;
434 	} else {
435 		luri = *uri;
436 	}
437 
438 	if (unlikely(luri.len > MAX_URI_SIZE - 1)) {
439 		LM_ERR("too long uri: %.*s\n", luri.len, luri.s);
440 		return -1;
441 	}
442 
443 	/* copy the dst_uri */
444 	if (dst_uri && dst_uri->len && dst_uri->s) {
445 		if (unlikely(dst_uri->len > MAX_URI_SIZE - 1)) {
446 			LM_ERR("too long dst_uri: %.*s\n", dst_uri->len, dst_uri->s);
447 			return -1;
448 		}
449 		memcpy(branches[nr_branches].dst_uri, dst_uri->s, dst_uri->len);
450 		branches[nr_branches].dst_uri[dst_uri->len] = 0;
451 		branches[nr_branches].dst_uri_len = dst_uri->len;
452 	} else {
453 		branches[nr_branches].dst_uri[0] = '\0';
454 		branches[nr_branches].dst_uri_len = 0;
455 	}
456 
457 	/* copy the path string */
458 	if (unlikely(path && path->len && path->s)) {
459 		if (unlikely(path->len > MAX_PATH_SIZE - 1)) {
460 			LM_ERR("too long path: %.*s\n", path->len, path->s);
461 			return -1;
462 		}
463 		memcpy(branches[nr_branches].path, path->s, path->len);
464 		branches[nr_branches].path[path->len] = 0;
465 		branches[nr_branches].path_len = path->len;
466 	} else {
467 		branches[nr_branches].path[0] = '\0';
468 		branches[nr_branches].path_len = 0;
469 	}
470 
471 	/* copy the ruri */
472 	memcpy(branches[nr_branches].uri, luri.s, luri.len);
473 	branches[nr_branches].uri[luri.len] = 0;
474 	branches[nr_branches].len = luri.len;
475 	branches[nr_branches].q = q;
476 
477 	branches[nr_branches].force_send_socket = force_socket;
478 	branches[nr_branches].flags = flags;
479 
480 	/* copy instance string */
481 	if (unlikely(instance && instance->len && instance->s)) {
482 		if (unlikely(instance->len > MAX_INSTANCE_SIZE - 1)) {
483 			LM_ERR("too long instance: %.*s\n",
484 			    instance->len, instance->s);
485 			return -1;
486 		}
487 		memcpy(branches[nr_branches].instance, instance->s,
488 		       instance->len);
489 		branches[nr_branches].instance[instance->len] = 0;
490 		branches[nr_branches].instance_len = instance->len;
491 	} else {
492 		branches[nr_branches].instance[0] = '\0';
493 		branches[nr_branches].instance_len = 0;
494 	}
495 
496 	/* copy reg_id */
497 	branches[nr_branches].reg_id = reg_id;
498 
499 	/* copy ruid string */
500 	if (unlikely(ruid && ruid->len && ruid->s)) {
501 		if (unlikely(ruid->len > MAX_RUID_SIZE - 1)) {
502 			LM_ERR("too long ruid: %.*s\n",
503 			    ruid->len, ruid->s);
504 			return -1;
505 		}
506 		memcpy(branches[nr_branches].ruid, ruid->s,
507 		       ruid->len);
508 		branches[nr_branches].ruid[ruid->len] = 0;
509 		branches[nr_branches].ruid_len = ruid->len;
510 	} else {
511 		branches[nr_branches].ruid[0] = '\0';
512 		branches[nr_branches].ruid_len = 0;
513 	}
514 
515 	if (unlikely(location_ua && location_ua->len && location_ua->s)) {
516 		if (unlikely(location_ua->len > MAX_UA_SIZE)) {
517 			LM_ERR("too long location_ua: %.*s\n",
518 			    location_ua->len, location_ua->s);
519 			return -1;
520 		}
521 		memcpy(branches[nr_branches].location_ua, location_ua->s,
522 		       location_ua->len);
523 		branches[nr_branches].location_ua[location_ua->len] = 0;
524 		branches[nr_branches].location_ua_len = location_ua->len;
525 	} else {
526 		branches[nr_branches].location_ua[0] = '\0';
527 		branches[nr_branches].location_ua_len = 0;
528 	}
529 
530 	nr_branches++;
531 	return 1;
532 }
533 
534 
535 /**  Push a new branch to the current destination set.
536  * @param msg sip message, used for getting the uri if not specified (0).
537  * @param uri uri, can be 0 (in which case the uri is taken from msg)
538  * @param dst_uri destination uri, can be 0.
539  * @param path path vector (passed in a string), can be 0.
540  * @param q  q value.
541  * @param flags per branch flags.
542  * @param force_socket socket that should be used when sending.
543  * @param instance sip instance contact header param value
544  * @param reg_id reg-id contact header param value
545  * @param ruid ruid value from usrloc
546  * @param location_ua location user agent
547  *
548  * @return NULL on failure, new branch pointer on success.
549  */
ksr_push_branch(struct sip_msg * msg,str * uri,str * dst_uri,str * path,qvalue_t q,unsigned int flags,struct socket_info * force_socket,str * instance,unsigned int reg_id,str * ruid,str * location_ua)550 branch_t* ksr_push_branch(struct sip_msg* msg, str* uri, str* dst_uri, str* path,
551 		  qvalue_t q, unsigned int flags,
552 		  struct socket_info* force_socket,
553 		  str* instance, unsigned int reg_id,
554 		  str* ruid, str* location_ua)
555 {
556 	if(append_branch(msg, uri, dst_uri, path, q, flags, force_socket,
557 				instance, reg_id, ruid, location_ua)<0) {
558 		return NULL;
559 	}
560 	return &branches[nr_branches-1];
561 }
562 
563 /*! \brief
564  * Combines the given elements into a Contact header field
565  * dest = target buffer, will be updated to new position after the printed contact
566  * uri, q = contact elements
567  * end = end of target buffer
568  * Returns 0 on success or -1 on error (buffer is too short)
569  */
print_contact_str(char ** dest,str * uri,qvalue_t q,str * path,unsigned int flags,char * end,int options)570 static int print_contact_str(char **dest, str *uri, qvalue_t q, str *path, unsigned int flags, char *end, int options)
571 {
572 	char *p = *dest;
573 	str buf;
574 
575 	/* uri */
576 	if (p + uri->len + 2 > end) {
577 		return -1;
578 	}
579 	*p++ = '<';
580 	memcpy(p, uri->s, uri->len);
581 	p += uri->len;
582 
583 	/* uri parameters */
584 	/* path vector as route header parameter */
585 	if ((options & DS_PATH) && path->len > 0) {
586 		if (p + ROUTE_PARAM_LEN + path->len > end) {
587 			return -1;
588 		}
589 		memcpy(p, ROUTE_PARAM, ROUTE_PARAM_LEN);
590 		p += ROUTE_PARAM_LEN;
591 		/* copy escaped path into dest */
592 		buf.s = p;
593 		buf.len = end - p;
594 		if (escape_param(path, &buf) < 0) {
595 			return -1;
596 		}
597 		p += buf.len;
598 	}
599 
600 	/* end of uri parameters */
601 	*p++ = '>';
602 
603 	/* header parameters */
604 	/* q value */
605 	if (q != Q_UNSPECIFIED) {
606 		buf.s = q2str(q, (unsigned int*)&buf.len);
607 		if (p + Q_PARAM_LEN + buf.len > end) {
608 			return -1;
609 		}
610 		memcpy(p, Q_PARAM, Q_PARAM_LEN);
611 		p += Q_PARAM_LEN;
612 		memcpy(p, buf.s, buf.len);
613 		p += buf.len;
614 	}
615 
616 	/* branch flags (not SIP standard conformant) */
617 	if (options & DS_FLAGS) {
618 		buf.s = int2str(flags, &buf.len);
619 		if (p + FLAGS_PARAM_LEN + buf.len > end) {
620 			return -1;
621 		}
622 		memcpy(p, FLAGS_PARAM, FLAGS_PARAM_LEN);
623 		p += FLAGS_PARAM_LEN;
624 		memcpy(p, buf.s, buf.len);
625 		p += buf.len;
626 	}
627 
628 	*dest = p;
629 	return 0;
630 }
631 
632 
633 /*
634  * Create a Contact header field from the dset
635  * array
636  */
print_dset(struct sip_msg * msg,int * len,int options)637 char* print_dset(struct sip_msg* msg, int* len, int options)
638 {
639 	int cnt = 0;
640 	qvalue_t q;
641 	str uri, path;
642 	unsigned int flags;
643 	char *p;
644 	int crt_branch;
645 	static char dset[MAX_REDIRECTION_LEN];
646 	char *end = dset + MAX_REDIRECTION_LEN;
647 
648 	/* backup current branch index to restore it later */
649 	crt_branch = get_branch_iterator();
650 
651 	/* contact header name */
652 	if (CONTACT_LEN + CRLF_LEN + 1 > MAX_REDIRECTION_LEN) {
653 		goto memfail;
654 	}
655 	memcpy(dset, CONTACT, CONTACT_LEN);
656 	p = dset + CONTACT_LEN;
657 
658 	/* current uri */
659 	if (msg->new_uri.s) {
660 		if (print_contact_str(&p, &msg->new_uri, ruri_q, &msg->path_vec, ruri_bflags, end, options) < 0) {
661 			goto memfail;
662 		}
663 		cnt++;
664 	}
665 
666 	/* branches */
667 	init_branch_iterator();
668 	while ((uri.s = next_branch(&uri.len, &q, 0, &path, &flags, 0, 0, 0, 0))) {
669 		if (cnt > 0) {
670 			if (p + CONTACT_DELIM_LEN > end) {
671 				goto memfail;
672 			}
673 			memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
674 			p += CONTACT_DELIM_LEN;
675 		}
676 
677 		if (print_contact_str(&p, &uri, q, &path, flags, end, options) < 0) {
678 			goto memfail;
679 		}
680 
681 		cnt++;
682 	}
683 
684 	if (cnt == 0) {
685 		LM_WARN("no r-uri or branches\n");
686 		goto error;
687 	}
688 
689 	if (p + CRLF_LEN + 1 > end) {
690 		goto memfail;
691 	}
692 	memcpy(p, CRLF " ", CRLF_LEN + 1);
693 	*len = p - dset + CRLF_LEN;
694 	set_branch_iterator(crt_branch);
695 	return dset;
696 
697 memfail:
698 	LM_ERR("redirection buffer length exceed\n");
699 error:
700 	*len = 0;
701 	set_branch_iterator(crt_branch);
702 	return 0;
703 }
704 
705 
706 /*
707  * Sets the q parameter of the Request-URI
708  */
set_ruri_q(qvalue_t q)709 void set_ruri_q(qvalue_t q)
710 {
711 	ruri_q = q;
712 }
713 
714 
715 /*
716  * Return the q value of the Request-URI
717  */
get_ruri_q(void)718 qvalue_t get_ruri_q(void)
719 {
720 	return ruri_q;
721 }
722 
723 
724 
725 /*
726  * Rewrite Request-URI
727  */
rewrite_uri(struct sip_msg * _m,str * _s)728 int rewrite_uri(struct sip_msg* _m, str* _s)
729 {
730 	char *buf = NULL;
731 
732 	if(_m->new_uri.s==NULL || _m->new_uri.len<_s->len) {
733 		buf = (char*)pkg_malloc(_s->len + 1);
734 		if (!buf) {
735 			PKG_MEM_ERROR;
736 			return -1;
737 		}
738 	}
739 	if(buf!=NULL) {
740 		if(_m->new_uri.s)
741 			pkg_free(_m->new_uri.s);
742 	} else {
743 		buf = _m->new_uri.s;
744 	}
745 
746 	memcpy(buf, _s->s, _s->len);
747 	buf[_s->len] = '\0';
748 
749 	_m->parsed_uri_ok = 0;
750 
751 	_m->new_uri.s = buf;
752 	_m->new_uri.len = _s->len;
753 	/* mark ruri as new and available for forking */
754 	ruri_mark_new();
755 
756 	return 1;
757 }
758 
759 /**
760  * return src ip, port and proto as a SIP uri or proxy address
761  * - value stored in a static buffer
762  * - mode=0 return uri, mode=1 return proxy address
763  */
msg_get_src_addr(sip_msg_t * msg,str * uri,int mode)764 int msg_get_src_addr(sip_msg_t *msg, str *uri, int mode)
765 {
766 	static char buf[80];
767 	char* p;
768 	str ip, port;
769 	int len;
770 	str proto;
771 
772 	if (msg==NULL || uri==NULL) {
773 		LM_ERR("invalid parameter value\n");
774 		return -1;
775 	}
776 
777 	ip.s = ip_addr2a(&msg->rcv.src_ip);
778 	ip.len = strlen(ip.s);
779 
780 	port.s = int2str(msg->rcv.src_port, &port.len);
781 
782 	switch(msg->rcv.proto) {
783 		case PROTO_NONE:
784 		case PROTO_UDP:
785 			if(mode==0) {
786 				proto.s = 0; /* Do not add transport parameter, UDP is default */
787 				proto.len = 0;
788 			} else {
789 				proto.s = "udp";
790 				proto.len = 3;
791 			}
792 		break;
793 
794 		case PROTO_TCP:
795 			proto.s = "tcp";
796 			proto.len = 3;
797 		break;
798 
799 		case PROTO_TLS:
800 			proto.s = "tls";
801 			proto.len = 3;
802 		break;
803 
804 		case PROTO_SCTP:
805 			proto.s = "sctp";
806 			proto.len = 4;
807 		break;
808 
809 		case PROTO_WS:
810 		case PROTO_WSS:
811 			proto.s = "ws";
812 			proto.len = 2;
813 		break;
814 
815 		default:
816 			LM_ERR("unknown transport protocol\n");
817 		return -1;
818 	}
819 
820 	len = ip.len + 2*(msg->rcv.src_ip.af==AF_INET6)+ 1 + port.len;
821 	if (mode==0) {
822 		len += 4;
823 		if(proto.s) {
824 			len += TRANSPORT_PARAM_LEN;
825 			len += proto.len;
826 		}
827 	} else {
828 		len += proto.len + 1;
829 	}
830 
831 	if (len > 79) {
832 		LM_ERR("buffer too small\n");
833 		return -1;
834 	}
835 
836 	p = buf;
837 	if(mode==0) {
838 		memcpy(p, "sip:", 4);
839 		p += 4;
840 	} else {
841 		memcpy(p, proto.s, proto.len);
842 		p += proto.len;
843 		*p++ = ':';
844 	}
845 
846 	if (msg->rcv.src_ip.af==AF_INET6)
847 		*p++ = '[';
848 	memcpy(p, ip.s, ip.len);
849 	p += ip.len;
850 	if (msg->rcv.src_ip.af==AF_INET6)
851 		*p++ = ']';
852 
853 	*p++ = ':';
854 
855 	memcpy(p, port.s, port.len);
856 	p += port.len;
857 
858 	if (mode==0 && proto.s) {
859 		memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN);
860 		p += TRANSPORT_PARAM_LEN;
861 
862 		memcpy(p, proto.s, proto.len);
863 	}
864 
865 	uri->s = buf;
866 	uri->len = len;
867 	uri->s[uri->len] = '\0';
868 
869 	return 0;
870 }
871 
872 /**
873  * add alias parameter with encoding of source address
874  * - nuri->s must point to a buffer of nuri->len size
875  */
uri_add_rcv_alias(sip_msg_t * msg,str * uri,str * nuri)876 int uri_add_rcv_alias(sip_msg_t *msg, str *uri, str *nuri)
877 {
878 	char* p;
879 	str ip, port;
880 	int len;
881 
882 	if (msg==NULL || uri==NULL || nuri==NULL) {
883 		LM_ERR("invalid parameter value\n");
884 		return -1;
885 	}
886 
887 	ip.s = ip_addr2a(&msg->rcv.src_ip);
888 	ip.len = strlen(ip.s);
889 
890 	port.s = int2str(msg->rcv.src_port, &port.len);
891 
892 	/*uri;alias=[ip]~port~proto*/
893 	len = uri->len+ip.len+port.len+12;
894 	if(len>=nuri->len) {
895 		LM_ERR("not enough space - new uri len: %d (buf size: %d)\n",
896 				len, nuri->len);
897 		return -1;
898 	}
899 	p = nuri->s;
900 	memcpy(p, uri->s, uri->len);
901 	p += uri->len;
902 	memcpy(p, ";alias=", 7);
903 	p += 7;
904 	if (msg->rcv.src_ip.af == AF_INET6)
905 		*p++ = '[';
906 	memcpy(p, ip.s, ip.len);
907 	p += ip.len;
908 	if (msg->rcv.src_ip.af == AF_INET6)
909 		*p++ = ']';
910 	*p++ = '~';
911 	memcpy(p, port.s, port.len);
912 	p += port.len;
913 	*p++ = '~';
914 	*p++ = msg->rcv.proto + '0';
915 	nuri->len = p - nuri->s;
916 	nuri->s[nuri->len] = '\0';
917 
918 	LM_DBG("encoded <%.*s> => [%.*s]\n",
919 			uri->len, uri->s, nuri->len, nuri->s);
920 	return 0;
921 }
922 
923 /**
924  * restore from alias parameter with encoding of source address
925  * - nuri->s must point to a buffer of nuri->len size
926  * - suri->s must point to a buffer of suri->len size
927  */
uri_restore_rcv_alias(str * uri,str * nuri,str * suri)928 int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
929 {
930 	char* p;
931 	str skip;
932 	str ip, port, sproto;
933 	int proto;
934 
935 	if (uri==NULL || nuri==NULL || suri==NULL) {
936 		LM_ERR("invalid parameter value\n");
937 		return -1;
938 	}
939 
940 	/* sip:x;alias=1.1.1.1~0~0 */
941 	if(uri->len < 23) {
942 		/* no alias possible */
943 		return -2;
944 	}
945 	p = uri->s + uri->len-18;
946 	skip.s = 0;
947 	while(p>uri->s+5) {
948 		if(strncmp(p, ";alias=", 7)==0) {
949 			skip.s = p;
950 			break;
951 		}
952 		p--;
953 	}
954 	if(skip.s==0) {
955 		/* alias parameter not found */
956 		return -2;
957 	}
958 	p += 7;
959 	ip.s = p;
960 	p = (char*)memchr(ip.s, '~', (size_t)(uri->s+uri->len-ip.s));
961 	if(p==NULL) {
962 		/* proper alias parameter not found */
963 		return -2;
964 	}
965 	ip.len = p - ip.s;
966 	p++;
967 	if(p>=uri->s+uri->len) {
968 		/* proper alias parameter not found */
969 		return -2;
970 	}
971 	port.s = p;
972 	p = (char*)memchr(port.s, '~', (size_t)(uri->s+uri->len-port.s));
973 	if(p==NULL) {
974 		/* proper alias parameter not found */
975 		return -2;
976 	}
977 	port.len = p - port.s;
978 	p++;
979 	if(p>=uri->s+uri->len) {
980 		/* proper alias parameter not found */
981 		return -2;
982 	}
983 	proto = (int)(*p - '0');
984 	p++;
985 
986 	if(p!=uri->s+uri->len && *p!=';') {
987 		/* proper alias parameter not found */
988 		return -2;
989 	}
990 	skip.len = (int)(p - skip.s);
991 
992 	if(suri->len<=4+ip.len+1+port.len+11/*;transport=*/+4) {
993 		LM_ERR("address buffer too small\n");
994 		return -1;
995 	}
996 	if(nuri->len<=uri->len - skip.len) {
997 		LM_ERR("uri buffer too small\n");
998 		return -1;
999 	}
1000 
1001 	p = nuri->s;
1002 	memcpy(p, uri->s, (size_t)(skip.s-uri->s));
1003 	p += skip.s-uri->s;
1004 	memcpy(p, skip.s+skip.len, (size_t)(uri->s+uri->len - skip.s - skip.len));
1005 	p += uri->s+uri->len - skip.s - skip.len;
1006 	nuri->len = p - nuri->s;
1007 
1008 	p = suri->s;
1009 	memcpy(p, "sip:", 4);
1010 	p += 4;
1011 	memcpy(p, ip.s, ip.len);
1012 	p += ip.len;
1013 	*p++ = ':';
1014 	memcpy(p, port.s, port.len);
1015 	p += port.len;
1016 	proto_type_to_str((unsigned short)proto, &sproto);
1017 	if(sproto.len>0 && proto!=PROTO_UDP) {
1018 		memcpy(p, ";transport=", 11);
1019 		p += 11;
1020 		memcpy(p, sproto.s, sproto.len);
1021 		p += sproto.len;
1022 	}
1023 	suri->len = p - suri->s;
1024 
1025 	LM_DBG("decoded <%.*s> => [%.*s] [%.*s]\n",
1026 			uri->len, uri->s, nuri->len, nuri->s, suri->len, suri->s);
1027 
1028 	return 0;
1029 }
1030 
1031 
1032 /**
1033  * trim alias parameter from uri
1034  * - nuri->s must point to a buffer of nuri->len size
1035  */
uri_trim_rcv_alias(str * uri,str * nuri)1036 int uri_trim_rcv_alias(str *uri, str *nuri)
1037 {
1038 	char *p;
1039 	str skip;
1040 	str ip, port;
1041 
1042 	if(uri == NULL || nuri == NULL) {
1043 		LM_ERR("invalid parameter value\n");
1044 		return -1;
1045 	}
1046 
1047 	/* sip:x;alias=1.1.1.1~0~0 */
1048 	if(uri->len < 23) {
1049 		/* no alias possible */
1050 		return 0;
1051 	}
1052 	p = uri->s + uri->len - 18;
1053 	skip.s = 0;
1054 	while(p > uri->s + 5) {
1055 		if(strncmp(p, ";alias=", 7) == 0) {
1056 			skip.s = p;
1057 			break;
1058 		}
1059 		p--;
1060 	}
1061 	if(skip.s == 0) {
1062 		/* alias parameter not found */
1063 		return 0;
1064 	}
1065 	p += 7;
1066 	ip.s = p;
1067 	p = (char *)memchr(ip.s, '~', (size_t)(uri->s + uri->len - ip.s));
1068 	if(p == NULL) {
1069 		/* proper alias parameter not found */
1070 		return 0;
1071 	}
1072 	ip.len = p - ip.s;
1073 	p++;
1074 	if(p >= uri->s + uri->len) {
1075 		/* proper alias parameter not found */
1076 		return 0;
1077 	}
1078 	port.s = p;
1079 	p = (char *)memchr(port.s, '~', (size_t)(uri->s + uri->len - port.s));
1080 	if(p == NULL) {
1081 		/* proper alias parameter not found */
1082 		return 0;
1083 	}
1084 	port.len = p - port.s;
1085 	p++;
1086 	if(p >= uri->s + uri->len) {
1087 		/* proper alias parameter not found */
1088 		return 0;
1089 	}
1090 	/* jump over proto */
1091 	p++;
1092 
1093 	if(p != uri->s + uri->len && *p != ';') {
1094 		/* proper alias parameter not found */
1095 		return 0;
1096 	}
1097 	skip.len = (int)(p - skip.s);
1098 	if(nuri->len <= uri->len - skip.len) {
1099 		LM_ERR("uri buffer too small\n");
1100 		return -1;
1101 	}
1102 
1103 	p = nuri->s;
1104 	memcpy(p, uri->s, (size_t)(skip.s - uri->s));
1105 	p += skip.s - uri->s;
1106 	memcpy(p, skip.s + skip.len,
1107 			(size_t)(uri->s + uri->len - skip.s - skip.len));
1108 	p += uri->s + uri->len - skip.s - skip.len;
1109 	nuri->len = p - nuri->s;
1110 
1111 	LM_DBG("decoded <%.*s> => [%.*s]\n", uri->len, uri->s, nuri->len, nuri->s);
1112 	return 1;
1113 }
1114 
1115 /* address of record (aor) management */
1116 
1117 /* address of record considered case sensitive
1118  * - 0 = no; 1 = yes */
1119 static int aor_case_sensitive=0;
1120 
set_aor_case_sensitive(int mode)1121 int set_aor_case_sensitive(int mode)
1122 {
1123 	int r;
1124 	r = aor_case_sensitive;
1125 	aor_case_sensitive = mode;
1126 	return r;
1127 }
1128 
get_aor_case_sensitive(void)1129 int get_aor_case_sensitive(void)
1130 {
1131 	return aor_case_sensitive;
1132 }
1133