1 /*
2 * Copyright (C) 2008 Daniel-Constantin Mierla (asipto.com)
3 *
4 * This file is part of Kamailio, a free SIP server.
5 *
6 * Kamailio is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
10 *
11 * Kamailio is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22 #include "../../core/parser/parse_uri.h"
23 #include "../../core/dset.h"
24 #include "../../core/onsend.h"
25 #include "../../core/socket_info.h"
26
27 #include "pv_core.h"
28 #include "pv_branch.h"
29
30 static branch_t _pv_sbranch;
31
pv_init_sbranch(void)32 void pv_init_sbranch(void)
33 {
34 memset(&_pv_sbranch, 0, sizeof(branch_t));
35 }
36
pv_get_branchx_helper(sip_msg_t * msg,pv_param_t * param,pv_value_t * res,int btype)37 int pv_get_branchx_helper(sip_msg_t *msg, pv_param_t *param,
38 pv_value_t *res, int btype)
39 {
40 int idx = 0;
41 int idxf = 0;
42 branch_t *br;
43
44 if(btype==1) {
45 br = &_pv_sbranch;
46 } else {
47 /* get the index */
48 if(pv_get_spec_index(msg, param, &idx, &idxf)!=0)
49 {
50 LM_ERR("invalid index\n");
51 return pv_get_null(msg, param, res);
52 }
53 br = get_sip_branch(idx);
54 if(br==NULL) {
55 return pv_get_null(msg, param, res);
56 }
57 }
58
59 /* branch(count) doesn't need a valid branch, everything else does */
60 if(br->len == 0 && ( param->pvn.u.isname.name.n != 5/* count*/ ))
61 {
62 LM_ERR("error accessing branch [%d]\n", idx);
63 return pv_get_null(msg, param, res);
64 }
65
66 switch(param->pvn.u.isname.name.n)
67 {
68 case 1: /* dst uri */
69 if(br->dst_uri_len==0)
70 return pv_get_null(msg, param, res);
71 return pv_get_strlval(msg, param, res, br->dst_uri, br->dst_uri_len);
72 case 2: /* path */
73 if(br->path_len==0)
74 return pv_get_null(msg, param, res);
75 return pv_get_strlval(msg, param, res, br->path, br->path_len);
76 case 3: /* Q */
77 if(br->q == Q_UNSPECIFIED)
78 return pv_get_null(msg, param, res);
79 return pv_get_sintval(msg, param, res, br->q);
80 case 4: /* send socket */
81 if(br->force_send_socket!=0)
82 return pv_get_strval(msg, param, res, &br->force_send_socket->sock_str);
83 return pv_get_null(msg, param, res);
84 case 5: /* count */
85 return pv_get_uintval(msg, param, res, nr_branches);
86 case 6: /* flags */
87 return pv_get_uintval(msg, param, res, br->flags);
88 case 7: /* ruid */
89 if(br->ruid_len==0)
90 return pv_get_null(msg, param, res);
91 return pv_get_strlval(msg, param, res, br->ruid, br->ruid_len);
92 case 8: /* location_ua */
93 if(br->location_ua_len==0)
94 return pv_get_null(msg, param, res);
95 return pv_get_strlval(msg, param, res, br->location_ua, br->location_ua_len);
96 case 9: /* otcpid */
97 return pv_get_uintval(msg, param, res, br->otcpid);
98 case 10: /* instance */
99 if(br->instance_len==0)
100 return pv_get_null(msg, param, res);
101 return pv_get_strlval(msg, param, res, br->instance, br->instance_len);
102 default:
103 /* 0 - uri */
104 return pv_get_strlval(msg, param, res, br->uri, br->len);
105 }
106
107 return 0;
108 }
109
pv_get_branchx(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)110 int pv_get_branchx(sip_msg_t *msg, pv_param_t *param,
111 pv_value_t *res)
112 {
113 return pv_get_branchx_helper(msg, param, res, 0);
114 }
115
pv_set_branchx_helper(sip_msg_t * msg,pv_param_t * param,int op,pv_value_t * val,int btype)116 int pv_set_branchx_helper(sip_msg_t *msg, pv_param_t *param,
117 int op, pv_value_t *val, int btype)
118 {
119 int idx = 0;
120 int idxf = 0;
121 branch_t *br;
122 struct socket_info *si;
123 int port, proto;
124 str host;
125 char backup;
126
127 if(msg==NULL || param==NULL)
128 {
129 LM_ERR("bad parameters\n");
130 return -1;
131 }
132
133 if(btype==1) {
134 br = &_pv_sbranch;
135 } else {
136 /* get the index */
137 if(pv_get_spec_index(msg, param, &idx, &idxf)!=0)
138 {
139 LM_ERR("invalid index\n");
140 return -1;
141 }
142 if(idx<0)
143 {
144 if((int)nr_branches + idx >= 0) {
145 idx += nr_branches;
146 } else {
147 LM_ERR("index too low: %d (%u)\n", idx, nr_branches);
148 return -1;
149 }
150 }
151 LM_DBG("managing branch index %d (%u)\n", idx, nr_branches);
152 br = get_sip_branch(idx);
153 }
154
155 if(br==NULL)
156 {
157 LM_DBG("no branch to operate on\n");
158 return -1;
159 }
160
161 switch(param->pvn.u.isname.name.n)
162 {
163 case 1: /* dst uri */
164 if(val==NULL || (val->flags&PV_VAL_NULL))
165 {
166 br->dst_uri[0] = '\0';
167 br->dst_uri_len = 0;
168 break;
169 }
170 if(!(val->flags&PV_VAL_STR))
171 {
172 LM_ERR("str value required to set branch dst uri\n");
173 return -1;
174 }
175 if(val->rs.len<=0)
176 {
177 br->dst_uri[0] = '\0';
178 br->dst_uri_len = 0;
179 break;
180 }
181
182 if (unlikely(val->rs.len > MAX_URI_SIZE - 1))
183 {
184 LM_ERR("too long dst uri: %.*s\n",
185 val->rs.len, val->rs.s);
186 return -1;
187 }
188 memcpy(br->dst_uri, val->rs.s, val->rs.len);
189 br->dst_uri[val->rs.len] = 0;
190 br->dst_uri_len = val->rs.len;
191 break;
192 case 2: /* path */
193 if(val==NULL || (val->flags&PV_VAL_NULL))
194 {
195 br->path[0] = '\0';
196 br->path_len = 0;
197 break;
198 }
199 if(!(val->flags&PV_VAL_STR))
200 {
201 LM_ERR("str value required to set branch path\n");
202 return -1;
203 }
204 if(val->rs.len<=0)
205 {
206 br->path[0] = '\0';
207 br->path_len = 0;
208 break;
209 }
210
211 if (unlikely(val->rs.len > MAX_PATH_SIZE - 1))
212 {
213 LM_ERR("path too long: %.*s\n",
214 val->rs.len, val->rs.s);
215 return -1;
216 }
217 memcpy(br->path, val->rs.s, val->rs.len);
218 br->path[val->rs.len] = 0;
219 br->path_len = val->rs.len;
220 break;
221 case 3: /* Q */
222 if(val==NULL || (val->flags&PV_VAL_NULL))
223 {
224 br->q = Q_UNSPECIFIED;
225 break;
226 }
227 if(!(val->flags&PV_VAL_INT))
228 {
229 LM_ERR("int value required to set branch q\n");
230 return -1;
231 }
232 br->q = val->ri;
233 break;
234 case 4: /* send socket */
235 if(val==NULL || (val->flags&PV_VAL_NULL))
236 {
237 br->force_send_socket = NULL;
238 break;
239 }
240 if(!(val->flags&PV_VAL_STR))
241 {
242 LM_ERR("str value required to set branch send sock\n");
243 return -1;
244 }
245 if(val->rs.len<=0)
246 {
247 br->force_send_socket = NULL;
248 break;
249 }
250 STR_VTOZ(val->rs.s[val->rs.len], backup);
251 if (parse_phostport(val->rs.s, &host.s, &host.len, &port,
252 &proto) < 0)
253 {
254 LM_ERR("invalid socket specification\n");
255 STR_ZTOV(val->rs.s[val->rs.len], backup);
256 return -1;
257 }
258 STR_ZTOV(val->rs.s[val->rs.len], backup);
259 si = grep_sock_info(&host, (unsigned short)port,
260 (unsigned short)proto);
261 if (si!=NULL)
262 {
263 br->force_send_socket = si;
264 } else {
265 LM_WARN("no socket found to match [%.*s]\n",
266 val->rs.len, val->rs.s);
267 br->force_send_socket = NULL;
268 }
269 break;
270 case 5: /* count */
271 /* do nothing - cannot set the branch counter */
272 break;
273 case 6: /* flags */
274 if(val==NULL || (val->flags&PV_VAL_NULL))
275 {
276 br->flags = 0;
277 break;
278 }
279 if(!(val->flags&PV_VAL_INT))
280 {
281 LM_ERR("int value required to set branch flags\n");
282 return -1;
283 }
284 br->flags = val->ri;
285 break;
286 case 7: /* ruid */
287 /* do nothing - cannot set the ruid */
288 break;
289 case 8: /* location_ua */
290 /* do nothing - cannot set the location_ua */
291 break;
292 case 9: /* otcpid */
293 if(val==NULL || (val->flags&PV_VAL_NULL))
294 {
295 br->otcpid = 0;
296 break;
297 }
298 if(!(val->flags&PV_VAL_INT))
299 {
300 LM_ERR("int value required to set branch flags\n");
301 return -1;
302 }
303 br->otcpid = val->ri;
304 break;
305 case 10: /* instance */
306 /* do nothing - cannot set the instance */
307 break;
308 default:
309 /* 0 - uri */
310 if(val==NULL || (val->flags&PV_VAL_NULL))
311 {
312 if(btype==1) {
313 memset(br, 0, sizeof(branch_t));
314 } else {
315 drop_sip_branch(idx);
316 }
317 } else {
318 if(!(val->flags&PV_VAL_STR))
319 {
320 LM_ERR("str value required to set branch uri\n");
321 return -1;
322 }
323 if(val->rs.len<=0)
324 {
325 if(btype==1) {
326 memset(br, 0, sizeof(branch_t));
327 } else {
328 drop_sip_branch(idx);
329 }
330 } else {
331 if (unlikely(val->rs.len > MAX_URI_SIZE - 1))
332 {
333 LM_ERR("too long r-uri: %.*s\n",
334 val->rs.len, val->rs.s);
335 return -1;
336 }
337 memcpy(br->uri, val->rs.s, val->rs.len);
338 br->uri[val->rs.len] = 0;
339 br->len = val->rs.len;
340 }
341 }
342 }
343
344 return 0;
345 }
346
pv_set_branchx(sip_msg_t * msg,pv_param_t * param,int op,pv_value_t * val)347 int pv_set_branchx(sip_msg_t *msg, pv_param_t *param,
348 int op, pv_value_t *val)
349 {
350 return pv_set_branchx_helper(msg, param, op, val, 0);
351 }
352
pv_parse_branchx_name(pv_spec_p sp,str * in)353 int pv_parse_branchx_name(pv_spec_p sp, str *in)
354 {
355 if(sp==NULL || in==NULL || in->len<=0)
356 return -1;
357
358 switch(in->len)
359 {
360 case 1:
361 if(*in->s=='q' || *in->s=='Q')
362 sp->pvp.pvn.u.isname.name.n = 3;
363 else goto error;
364 break;
365 case 3:
366 if(strncmp(in->s, "uri", 3)==0)
367 sp->pvp.pvn.u.isname.name.n = 0;
368 else goto error;
369 break;
370 case 4:
371 if(strncmp(in->s, "path", 4)==0)
372 sp->pvp.pvn.u.isname.name.n = 2;
373 else if (strncmp(in->s, "ruid", 4)==0)
374 sp->pvp.pvn.u.isname.name.n = 7;
375 else goto error;
376 break;
377 case 5:
378 if(strncmp(in->s, "count", 5)==0)
379 sp->pvp.pvn.u.isname.name.n = 5;
380 else if(strncmp(in->s, "flags", 5)==0)
381 sp->pvp.pvn.u.isname.name.n = 6;
382 else goto error;
383 break;
384 case 6:
385 if(strncmp(in->s, "otcpid", 6)==0)
386 sp->pvp.pvn.u.isname.name.n = 9;
387 else goto error;
388 break;
389 case 7:
390 if(strncmp(in->s, "dst_uri", 7)==0)
391 sp->pvp.pvn.u.isname.name.n = 1;
392 else goto error;
393 break;
394 case 8:
395 if(strncmp(in->s, "instance", 8)==0)
396 sp->pvp.pvn.u.isname.name.n = 10;
397 else goto error;
398 break;
399 case 11:
400 if(strncmp(in->s, "send_socket", 11)==0)
401 sp->pvp.pvn.u.isname.name.n = 4;
402 else if(strncmp(in->s, "location_ua", 11)==0)
403 sp->pvp.pvn.u.isname.name.n = 8;
404 else goto error;
405 break;
406
407 default:
408 goto error;
409 }
410 sp->pvp.pvn.type = PV_NAME_INTSTR;
411 sp->pvp.pvn.u.isname.type = 0;
412
413 return 0;
414
415 error:
416 LM_ERR("unknown PV branch name %.*s\n", in->len, in->s);
417 return -1;
418 }
419
pv_get_sbranch(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)420 int pv_get_sbranch(sip_msg_t *msg, pv_param_t *param,
421 pv_value_t *res)
422 {
423 return pv_get_branchx_helper(msg, param, res, 1);
424 }
425
pv_set_sbranch(sip_msg_t * msg,pv_param_t * param,int op,pv_value_t * val)426 int pv_set_sbranch(sip_msg_t *msg, pv_param_t *param,
427 int op, pv_value_t *val)
428 {
429 return pv_set_branchx_helper(msg, param, op, val, 1);
430 }
431
pv_get_sndfrom(struct sip_msg * msg,pv_param_t * param,pv_value_t * res)432 int pv_get_sndfrom(struct sip_msg *msg, pv_param_t *param,
433 pv_value_t *res)
434 {
435 struct onsend_info* snd_inf;
436 str s;
437
438 snd_inf=get_onsend_info();
439 if (! likely(snd_inf && snd_inf->send_sock))
440 return pv_get_null(msg, param, res);
441
442 switch(param->pvn.u.isname.name.n)
443 {
444 case 1: /* af */
445 return pv_get_uintval(msg, param, res,
446 (int)snd_inf->send_sock->address.af);
447 case 2: /* port */
448 return pv_get_uintval(msg, param, res,
449 (int)snd_inf->send_sock->port_no);
450 case 3: /* proto */
451 return pv_get_uintval(msg, param, res,
452 (int)snd_inf->send_sock->proto);
453 case 4: /* buf */
454 s.s = snd_inf->buf;
455 s.len = snd_inf->len;
456 return pv_get_strval(msg, param, res, &s);
457 case 5: /* len */
458 return pv_get_uintval(msg, param, res,
459 (int)snd_inf->len);
460 case 6: /* sproto */
461 if(get_valid_proto_string((int)snd_inf->send_sock->proto,
462 0, 0, &s)<0)
463 return pv_get_null(msg, param, res);
464 return pv_get_strval(msg, param, res, &s);
465 default:
466 /* 0 - ip */
467 return pv_get_strval(msg, param, res,
468 &snd_inf->send_sock->address_str);
469 }
470
471 return 0;
472 }
473
pv_get_sndto(struct sip_msg * msg,pv_param_t * param,pv_value_t * res)474 int pv_get_sndto(struct sip_msg *msg, pv_param_t *param,
475 pv_value_t *res)
476 {
477 struct onsend_info* snd_inf;
478 struct ip_addr ip;
479 str s;
480
481 snd_inf=get_onsend_info();
482 if (! likely(snd_inf && snd_inf->send_sock))
483 return pv_get_null(msg, param, res);
484
485 switch(param->pvn.u.isname.name.n)
486 {
487 case 1: /* af */
488 return pv_get_uintval(msg, param, res,
489 (int)snd_inf->send_sock->address.af);
490 case 2: /* port */
491 return pv_get_uintval(msg, param, res,
492 (int)su_getport(snd_inf->to));
493 case 3: /* proto */
494 return pv_get_uintval(msg, param, res,
495 (int)snd_inf->send_sock->proto);
496 case 4: /* buf */
497 s.s = snd_inf->buf;
498 s.len = snd_inf->len;
499 return pv_get_strval(msg, param, res, &s);
500 case 5: /* len */
501 return pv_get_uintval(msg, param, res,
502 (int)snd_inf->len);
503 case 6: /* sproto */
504 if(get_valid_proto_string((int)snd_inf->send_sock->proto,
505 0, 0, &s)<0)
506 return pv_get_null(msg, param, res);
507 return pv_get_strval(msg, param, res, &s);
508 default:
509 /* 0 - ip */
510 su2ip_addr(&ip, snd_inf->to);
511 s.s = ip_addr2a(&ip);
512 s.len = strlen(s.s);
513 return pv_get_strval(msg, param, res, &s);
514 }
515
516 return 0;
517 }
518
pv_parse_snd_name(pv_spec_p sp,str * in)519 int pv_parse_snd_name(pv_spec_p sp, str *in)
520 {
521 if(sp==NULL || in==NULL || in->len<=0)
522 return -1;
523
524 switch(in->len)
525 {
526 case 2:
527 if(strncmp(in->s, "ip", 2)==0)
528 sp->pvp.pvn.u.isname.name.n = 0;
529 else if(strncmp(in->s, "af", 2)==0)
530 sp->pvp.pvn.u.isname.name.n = 1;
531 else goto error;
532 break;
533 case 3:
534 if(strncmp(in->s, "buf", 3)==0)
535 sp->pvp.pvn.u.isname.name.n = 4;
536 else if(strncmp(in->s, "len", 3)==0)
537 sp->pvp.pvn.u.isname.name.n = 5;
538 else goto error;
539 break;
540 case 4:
541 if(strncmp(in->s, "port", 4)==0)
542 sp->pvp.pvn.u.isname.name.n = 2;
543 else goto error;
544 break;
545 case 5:
546 if(strncmp(in->s, "proto", 5)==0)
547 sp->pvp.pvn.u.isname.name.n = 3;
548 else goto error;
549 break;
550 case 6:
551 if(strncmp(in->s, "sproto", 6)==0)
552 sp->pvp.pvn.u.isname.name.n = 6;
553 else goto error;
554 break;
555 default:
556 goto error;
557 }
558 sp->pvp.pvn.type = PV_NAME_INTSTR;
559 sp->pvp.pvn.u.isname.type = 0;
560
561 return 0;
562
563 error:
564 LM_ERR("unknown PV snd name %.*s\n", in->len, in->s);
565 return -1;
566 }
567
pv_get_rcv(struct sip_msg * msg,pv_param_t * param,pv_value_t * res)568 int pv_get_rcv(struct sip_msg *msg, pv_param_t *param,
569 pv_value_t *res)
570 {
571 sr_net_info_t *neti = NULL;
572 str s;
573
574 neti = ksr_evrt_rcvnetinfo_get();
575
576 if (neti==NULL || neti->rcv==NULL || neti->rcv->bind_address==NULL)
577 return pv_get_null(msg, param, res);
578
579 switch(param->pvn.u.isname.name.n)
580 {
581 case 1: /* buf */
582 s.s = neti->data.s;
583 s.len = neti->data.len;
584 return pv_get_strval(msg, param, res, &s);
585 case 2: /* len */
586 return pv_get_uintval(msg, param, res,
587 (int)neti->data.len);
588 case 3: /* proto */
589 return pv_get_uintval(msg, param, res, (int)neti->rcv->proto);
590 case 4: /* srcip */
591 s.s = ip_addr2a(&neti->rcv->src_ip);
592 s.len = strlen(s.s);
593 return pv_get_strval(msg, param, res, &s);
594 case 5: /* rcvip */
595 s.s = ip_addr2a(&neti->rcv->dst_ip);
596 s.len = strlen(s.s);
597 return pv_get_strval(msg, param, res, &s);
598 case 6: /* sproto */
599 if(get_valid_proto_string((int)neti->rcv->proto,
600 0, 0, &s)<0) {
601 return pv_get_null(msg, param, res);
602 }
603 return pv_get_strval(msg, param, res, &s);
604 case 7: /* srcport */
605 return pv_get_uintval(msg, param, res,
606 (int)neti->rcv->src_port);
607 case 8: /* rcvport */
608 return pv_get_uintval(msg, param, res,
609 (int)neti->rcv->dst_port);
610 default:
611 /* 0 - af */
612 return pv_get_uintval(msg, param, res,
613 (int)neti->rcv->bind_address->address.af);
614 }
615
616 return 0;
617 }
618
pv_parse_rcv_name(pv_spec_p sp,str * in)619 int pv_parse_rcv_name(pv_spec_p sp, str *in)
620 {
621 if(sp==NULL || in==NULL || in->len<=0)
622 return -1;
623
624 switch(in->len)
625 {
626 case 2:
627 if(strncmp(in->s, "af", 2)==0)
628 sp->pvp.pvn.u.isname.name.n = 0;
629 else goto error;
630 break;
631 case 3:
632 if(strncmp(in->s, "buf", 3)==0)
633 sp->pvp.pvn.u.isname.name.n = 1;
634 else if(strncmp(in->s, "len", 3)==0)
635 sp->pvp.pvn.u.isname.name.n = 2;
636 else goto error;
637 break;
638 case 5:
639 if(strncmp(in->s, "proto", 5)==0)
640 sp->pvp.pvn.u.isname.name.n = 3;
641 else if(strncmp(in->s, "srcip", 5)==0)
642 sp->pvp.pvn.u.isname.name.n = 4;
643 else if(strncmp(in->s, "rcvip", 5)==0)
644 sp->pvp.pvn.u.isname.name.n = 5;
645 else goto error;
646 break;
647 case 6:
648 if(strncmp(in->s, "sproto", 6)==0)
649 sp->pvp.pvn.u.isname.name.n = 6;
650 else goto error;
651 break;
652 case 7:
653 if(strncmp(in->s, "srcport", 7)==0)
654 sp->pvp.pvn.u.isname.name.n = 7;
655 else if(strncmp(in->s, "rcvport", 7)==0)
656 sp->pvp.pvn.u.isname.name.n = 8;
657 else goto error;
658 break;
659 default:
660 goto error;
661 }
662 sp->pvp.pvn.type = PV_NAME_INTSTR;
663 sp->pvp.pvn.u.isname.type = 0;
664
665 return 0;
666
667 error:
668 LM_ERR("unknown PV rcv name %.*s\n", in->len, in->s);
669 return -1;
670 }
671
pv_get_nh(struct sip_msg * msg,pv_param_t * param,pv_value_t * res)672 int pv_get_nh(struct sip_msg *msg, pv_param_t *param,
673 pv_value_t *res)
674 {
675 struct sip_uri parsed_uri;
676 str uri;
677
678 if(msg==NULL || res==NULL)
679 return -1;
680
681 if(msg->first_line.type == SIP_REPLY) /* REPLY doesnt have r/d-uri */
682 return pv_get_null(msg, param, res);
683
684 if (msg->dst_uri.s != NULL && msg->dst_uri.len>0)
685 {
686 uri = msg->dst_uri;
687 } else {
688 if (msg->new_uri.s!=NULL && msg->new_uri.len>0)
689 {
690 uri = msg->new_uri;
691 } else {
692 uri = msg->first_line.u.request.uri;
693 }
694 }
695 if(param->pvn.u.isname.name.n==0) /* uri */
696 {
697 return pv_get_strval(msg, param, res, &uri);
698 }
699 if(parse_uri(uri.s, uri.len, &parsed_uri)!=0)
700 {
701 LM_ERR("failed to parse nh uri [%.*s]\n", uri.len, uri.s);
702 return pv_get_null(msg, param, res);
703 }
704 if(param->pvn.u.isname.name.n==1) /* username */
705 {
706 if(parsed_uri.user.s==NULL || parsed_uri.user.len<=0)
707 return pv_get_null(msg, param, res);
708 return pv_get_strval(msg, param, res, &parsed_uri.user);
709 } else if(param->pvn.u.isname.name.n==2) /* domain */ {
710 if(parsed_uri.host.s==NULL || parsed_uri.host.len<=0)
711 return pv_get_null(msg, param, res);
712 return pv_get_strval(msg, param, res, &parsed_uri.host);
713 } else if(param->pvn.u.isname.name.n==3) /* port */ {
714 if(parsed_uri.port.s==NULL)
715 return pv_get_5060(msg, param, res);
716 return pv_get_strintval(msg, param, res, &parsed_uri.port,
717 (int)parsed_uri.port_no);
718 } else if(param->pvn.u.isname.name.n==4) /* protocol */ {
719 if(parsed_uri.transport_val.s==NULL)
720 return pv_get_udp(msg, param, res);
721 return pv_get_strintval(msg, param, res, &parsed_uri.transport_val,
722 (int)parsed_uri.proto);
723 }
724 LM_ERR("unknown specifier\n");
725 return pv_get_null(msg, param, res);
726 }
727
pv_parse_nh_name(pv_spec_p sp,str * in)728 int pv_parse_nh_name(pv_spec_p sp, str *in)
729 {
730 if(sp==NULL || in==NULL || in->len<=0)
731 return -1;
732
733 switch(in->len)
734 {
735 case 1:
736 if(strncmp(in->s, "u", 1)==0)
737 sp->pvp.pvn.u.isname.name.n = 0;
738 else if(strncmp(in->s, "U", 1)==0)
739 sp->pvp.pvn.u.isname.name.n = 1;
740 else if(strncmp(in->s, "d", 1)==0)
741 sp->pvp.pvn.u.isname.name.n = 2;
742 else if(strncmp(in->s, "p", 1)==0)
743 sp->pvp.pvn.u.isname.name.n = 3;
744 else if(strncmp(in->s, "P", 1)==0)
745 sp->pvp.pvn.u.isname.name.n = 4;
746 else goto error;
747 break;
748 default:
749 goto error;
750 }
751 sp->pvp.pvn.type = PV_NAME_INTSTR;
752 sp->pvp.pvn.u.isname.type = 0;
753
754 return 0;
755
756 error:
757 LM_ERR("unknown PV nh name %.*s\n", in->len, in->s);
758 return -1;
759 }
760
761 /**
762 *
763 */
sbranch_set_ruri(sip_msg_t * msg)764 int sbranch_set_ruri(sip_msg_t *msg)
765 {
766 str sv;
767 flag_t old_bflags;
768 branch_t *br;
769 int ret;
770
771 ret = 0;
772 br = &_pv_sbranch;
773 if(br->len==0)
774 return -1;
775
776 sv.s = br->uri;
777 sv.len = br->len;
778
779 if (rewrite_uri(msg, &sv) < 0) {
780 LM_ERR("unable to rewrite Request-URI\n");
781 ret = -3;
782 goto error;
783 }
784
785 /* reset next hop address */
786 reset_dst_uri(msg);
787 if(br->dst_uri_len>0) {
788 sv.s = br->dst_uri;
789 sv.len = br->dst_uri_len;
790 if (set_dst_uri(msg, &sv) < 0) {
791 ret = -3;
792 goto error;
793 }
794 }
795
796 reset_path_vector(msg);
797 if(br->path_len==0) {
798 sv.s = br->path;
799 sv.len = br->path_len;
800 if(set_path_vector(msg, &sv) < 0) {
801 ret = -4;
802 goto error;
803 }
804 }
805
806 reset_instance(msg);
807 if (br->instance_len) {
808 sv.s = br->instance;
809 sv.len = br->instance_len;
810 if (set_instance(msg, &sv) < 0) {
811 ret = -5;
812 goto error;
813 }
814 }
815
816 reset_ruid(msg);
817 if (br->ruid_len) {
818 sv.s = br->ruid;
819 sv.len = br->ruid_len;
820 if (set_ruid(msg, &sv) < 0) {
821 ret = -6;
822 goto error;
823 }
824 }
825
826 reset_ua(msg);
827 if (br->location_ua_len) {
828 sv.s = br->location_ua;
829 sv.len = br->location_ua_len;
830 if (set_ua(msg, &sv) < 0) {
831 ret = -7;
832 goto error;
833 }
834 }
835
836 if (br->force_send_socket)
837 set_force_socket(msg, br->force_send_socket);
838
839 msg->reg_id = br->reg_id;
840 msg->otcpid = br->otcpid;
841 set_ruri_q(br->q);
842 old_bflags = 0;
843 getbflagsval(0, &old_bflags);
844 setbflagsval(0, old_bflags|br->flags);
845
846 return 0;
847 error:
848 return ret;
849 }
850
851 /**
852 *
853 */
sbranch_append(sip_msg_t * msg)854 int sbranch_append(sip_msg_t *msg)
855 {
856 str uri = {0};
857 str duri = {0};
858 str path = {0};
859 str ruid = {0};
860 str location_ua = {0};
861 str instance = {0};
862 branch_t *br;
863 branch_t *newbr;
864
865 br = &_pv_sbranch;
866 if(br->len==0)
867 return -1;
868
869 uri.s = br->uri;
870 uri.len = br->len;
871
872 if(br->dst_uri_len) {
873 duri.s = br->dst_uri;
874 duri.len = br->dst_uri_len;
875 }
876 if(br->path_len) {
877 path.s = br->path;
878 path.len = br->path_len;
879 }
880 if(br->ruid_len) {
881 ruid.s = br->ruid;
882 ruid.len = br->ruid_len;
883 }
884 if(br->location_ua_len) {
885 location_ua.s = br->location_ua;
886 location_ua.len = br->location_ua_len;
887 }
888 if(br->instance_len) {
889 instance.s = br->instance;
890 instance.len = br->instance_len;
891 }
892
893 newbr = ksr_push_branch(msg, &uri, &duri, &path, br->q, br->flags,
894 br->force_send_socket, &instance, br->reg_id,
895 &ruid, &location_ua);
896 if(newbr==NULL) {
897 LM_ERR("failed to append static branch\n");
898 return -1;
899 }
900 newbr->otcpid = br->otcpid;
901 return 0;
902 }
903
904 /**
905 *
906 */
sbranch_reset(void)907 int sbranch_reset(void)
908 {
909 memset(&_pv_sbranch, 0, sizeof(branch_t));
910 return 0;
911 }
912