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