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