1 /*
2  * tm - transaction management module
3  *
4  * Copyright (C) 2001-2003 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 
24 
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <sys/uio.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <sys/un.h>
34 #include <ctype.h>
35 #include <string.h>
36 
37 #include "../../core/str.h"
38 #include "../../core/ut.h"
39 #include "../../core/dprint.h"
40 #include "../../core/mem/mem.h"
41 #include "../../core/usr_avp.h"
42 #include "../../core/parser/parser_f.h"
43 #include "../../core/parser/parse_from.h"
44 #include "../../core/parser/parse_rr.h"
45 #include "../../core/parser/parse_nameaddr.h"
46 #include "../../core/parser/parse_hname2.h"
47 #include "../../core/parser/contact/parse_contact.h"
48 #include "../../core/tsend.h"
49 #include "config.h"
50 #include "t_lookup.h"
51 #include "t_fwd.h"
52 #include "t_funcs.h"
53 #include "t_fifo.h"
54 
55 
56 /* AF_LOCAL is not defined on solaris */
57 #if !defined(AF_LOCAL)
58 #define AF_LOCAL AF_UNIX
59 #endif
60 #if !defined(PF_LOCAL)
61 #define PF_LOCAL PF_UNIX
62 #endif
63 
64 
65 /* solaris doesn't have SUN_LEN */
66 #ifndef SUN_LEN
67 #define SUN_LEN(sa)	 ( strlen((sa)->sun_path) + \
68 						(size_t)(((struct sockaddr_un*)0)->sun_path) )
69 #endif
70 
71 
72 #define TWRITE_PARAMS          20
73 #define TWRITE_VERSION_S       "0.3"
74 #define TWRITE_VERSION_LEN     (sizeof(TWRITE_VERSION_S)-1)
75 
76 #define eol_line_s(_i_)        ( iov_lines_eol[2*(_i_)].iov_base )
77 #define eol_line_len(_i_)      ( iov_lines_eol[2*(_i_)].iov_len )
78 
79 #define eol_line(_i_,_s_)      { eol_line_s(_i_) = (_s_).s; \
80 									eol_line_len(_i_) = (_s_).len; }
81 
82 #define IDBUF_LEN              128
83 #define ROUTE_BUFFER_MAX       512
84 #define APPEND_BUFFER_MAX      4096
85 #define CMD_BUFFER_MAX         128
86 
87 #define copy_route(s,len,rs,rlen) \
88 	do {\
89 		if(rlen+len+3 >= ROUTE_BUFFER_MAX){\
90 			LM_ERR("buffer overflow while copying new route\n");\
91 			goto error;\
92 		}\
93 		if(len){\
94 			append_chr(s,','); len++;\
95 		}\
96 		append_chr(s,'<');len++;\
97 		append_str(s,rs,rlen);\
98 		len += rlen; \
99 		append_chr(s,'>');len++;\
100 	} while(0)
101 
102 static struct iovec iov_lines_eol[2*TWRITE_PARAMS];
103 static struct iovec eol={"\n",1};
104 
105 static int sock;
106 
107 struct hdr_avp {
108 	str title;
109 	int type;
110 	str sval;
111 	int ival;
112 	struct hdr_avp *next;
113 };
114 
115 struct tw_append {
116 	str name;
117 	int add_body;
118 	struct hdr_avp *elems;
119 	struct tw_append *next;
120 };
121 
122 struct tw_info {
123 	str action;
124 	struct tw_append *append;
125 };
126 
127 #define ELEM_TYPE_AVP      "avp"
128 #define ELEM_TYPE_AVP_LEN  (sizeof(ELEM_TYPE_AVP)-1)
129 #define ELEM_TYPE_HDR      "hdr"
130 #define ELEM_TYPE_HDR_LEN  (sizeof(ELEM_TYPE_HDR)-1)
131 #define ELEM_TYPE_MSG      "msg"
132 #define ELEM_TYPE_MSG_LEN  (sizeof(ELEM_TYPE_MSG)-1)
133 #define ELEM_IS_AVP        (1<<0)
134 #define ELEM_IS_HDR        (1<<1)
135 #define ELEM_IS_MSG        (1<<2)
136 
137 #define ELEM_VAL_BODY      "body"
138 #define ELEM_VAL_BODY_LEN  (sizeof(ELEM_VAL_BODY)-1)
139 
140 
141 static struct tw_append *tw_appends;
142 
143 
print_tw_append(struct tw_append * append)144 static void print_tw_append( struct tw_append *append)
145 {
146 	struct hdr_avp *ha;
147 
148 	if (!append)
149 		return;
150 
151 	LM_DBG("tw_append name=<%.*s>\n",
152 		append->name.len,append->name.s);
153 	for( ha=append->elems ; ha ; ha=ha->next ) {
154 		LM_DBG("\ttitle=<%.*s>\n",ha->title.len,ha->title.s);
155 		LM_DBG("\t\tttype=<%d>\n",ha->type);
156 		LM_DBG("\t\tsval=<%.*s>\n",ha->sval.len,ha->sval.s);
157 		LM_DBG("\t\tival=<%d>\n",ha->ival);
158 	}
159 }
160 
161 
162 /* tw_append syntax:
163  * tw_append = name:element[;element]
164  * element   = [title=]value
165  * value     = avp[avp_spec] | hdr[hdr_name] | msg[body] */
parse_tw_append(modparam_t type,void * val)166 int parse_tw_append( modparam_t type, void* val)
167 {
168 	struct hdr_field hdr;
169 	struct hdr_avp *last;
170 	struct hdr_avp *ha=NULL;
171 	struct tw_append *app;
172 	int_str avp_name;
173 	char *s;
174 	char bar;
175 	str foo;
176 	int n;
177 	int index;
178 
179 	if (val==0 || ((char*)val)[0]==0)
180 		return 0;
181 	s = (char*)val;
182 
183 	/* start parsing - first the name */
184 	while( *s && isspace((int)*s) )  s++;
185 	if ( !*s || *s==':')
186 		goto parse_error;
187 	foo.s = s;
188 	while ( *s && *s!=':' && !isspace((int)*s) ) s++;
189 	if ( !*s || foo.s==s )
190 		goto parse_error;
191 	foo.len = s - foo.s;
192 	/* parse separator */
193 	while( *s && isspace((int)*s) )  s++;
194 	if ( !*s || *s!=':')
195 		goto parse_error;
196 	s++;
197 	while( *s && isspace((int)*s) )  s++;
198 	if ( !*s )
199 		goto parse_error;
200 
201 	/* check for name duplication */
202 	for(app=tw_appends;app;app=app->next)
203 		if (app->name.len==foo.len && !strncasecmp(app->name.s,foo.s,foo.len)){
204 			LM_ERR("duplicated tw_append name <%.*s>\n",foo.len,foo.s);
205 			goto error;
206 		}
207 
208 	/* new tw_append structure */
209 	app = (struct tw_append*)pkg_malloc( sizeof(struct tw_append) );
210 	if (app==0) {
211 		PKG_MEM_ERROR;
212 		goto error;
213 	}
214 	app->name.s = (char*)pkg_malloc( foo.len+1 );
215 	if (app->name.s==0) {
216 		PKG_MEM_ERROR;
217 		pkg_free(app);
218 		goto error;
219 	}
220 	memcpy( app->name.s, foo.s, foo.len);
221 	app->name.len = foo.len;
222 	app->name.s[app->name.len] = 0;
223 	last = app->elems = 0;
224 	app->next = tw_appends;
225 	tw_appends = app;
226 
227 	/* parse the elements */
228 	while (*s) {
229 		/* parse element title or element type */
230 		foo.s = s;
231 		while( *s && *s!='[' && *s!='=' && *s!=';' && !isspace((int)*s) ) s++;
232 		if ( !*s || foo.s==s)
233 			goto parse_error;
234 		foo.len = s - foo.s;
235 		/* new hdr_avp structure */
236 		ha = (struct hdr_avp*)pkg_malloc( sizeof(struct hdr_avp) );
237 		if (ha==0) {
238 			PKG_MEM_ERROR;
239 			goto error;
240 		}
241 		memset( ha, 0, sizeof(struct hdr_avp));
242 		if (*s!='[') {
243 			/* foo must by title or some error -> parse separator */
244 			while( *s && isspace((int)*s) )  s++;
245 			if ( !*s || *s!='=')
246 				goto parse_error;
247 			s++;
248 			while( *s && isspace((int)*s) )  s++;
249 			if ( !*s )
250 				goto parse_error;
251 			/* set the title */
252 			ha->title.s = (char*)pkg_malloc( foo.len+1 );
253 			if (ha->title.s==0) {
254 				PKG_MEM_ERROR;
255 				goto error;
256 			}
257 			memcpy( ha->title.s, foo.s, foo.len);
258 			ha->title.len = foo.len;
259 			ha->title.s[ha->title.len] = 0;
260 			/* parse the type now */
261 			foo.s = s;
262 			while( *s && *s!='[' && *s!=']' && *s!=';' && !isspace((int)*s) )
263 				s++;
264 			if ( *s!='[' || foo.s==s)
265 				goto parse_error;
266 			foo.len = s - foo.s;
267 		}
268 		/* foo containes the elemet type */
269 		if ( foo.len==ELEM_TYPE_AVP_LEN &&
270 		!strncasecmp( foo.s, ELEM_TYPE_AVP, foo.len) ) {
271 			ha->type = ELEM_IS_AVP;
272 		} else if ( foo.len==ELEM_TYPE_HDR_LEN &&
273 		!strncasecmp( foo.s, ELEM_TYPE_HDR, foo.len) ) {
274 			ha->type = ELEM_IS_HDR;
275 		} else if ( foo.len==ELEM_TYPE_MSG_LEN &&
276 		!strncasecmp( foo.s, ELEM_TYPE_MSG, foo.len) ) {
277 			ha->type = ELEM_IS_MSG;
278 		} else {
279 			LM_ERR("unknown type <%.*s>\n", foo.len, foo.s);
280 			goto error;
281 		}
282 		/* parse the element name */
283 		s++;
284 		foo.s = s;
285 		while( *s && *s!=']' && *s!=';' && !isspace((int)*s) ) s++;
286 		if ( *s!=']' || foo.s==s )
287 			goto parse_error;
288 		foo.len = s - foo.s;
289 		s++;
290 		/* process and optimize the element name */
291 		if (ha->type==ELEM_IS_AVP) {
292 			/* element is AVP */
293 			if ( parse_avp_spec( &foo, &n, &avp_name, &index)!=0 ) {
294 				LM_ERR("bad alias spec <%.*s>\n",foo.len, foo.s);
295 				goto error;
296 			}
297 			if (n&AVP_NAME_STR) {
298 				/* string name */
299 				ha->sval.s = (char*)pkg_malloc(avp_name.s.len+1);
300 				if (ha->sval.s==0) {
301 					PKG_MEM_ERROR;
302 					goto error;
303 				}
304 				memcpy( ha->sval.s, avp_name.s.s, avp_name.s.len);
305 				ha->sval.len = avp_name.s.len;
306 				ha->sval.s[ha->sval.len] = 0;
307 				if (ha->title.s==0)
308 					ha->title = ha->sval;
309 			} else {
310 				/* ID name - if title is missing, convert the ID to
311 				 * string and us it a title */
312 				ha->ival = avp_name.n;
313 				if (ha->title.s==0) {
314 					foo.s=int2str((unsigned long)ha->ival, &foo.len);
315 					ha->title.s = (char*)pkg_malloc( n+1 );
316 					if (ha->title.s==0) {
317 						PKG_MEM_ERROR;
318 						goto error;
319 					}
320 					memcpy( ha->title.s, foo.s, foo.len);
321 					ha->title.len = foo.len;
322 					ha->title.s[ha->title.len] = 0;
323 				}
324 			}
325 		} else if (ha->type==ELEM_IS_HDR) {
326 			/* element is HDR -  try to get it's coded type if defined */
327 			bar = foo.s[foo.len];
328 			foo.s[foo.len] = ':';
329 			/* parse header name */
330 			if (parse_hname2( foo.s, foo.s+foo.len+1, &hdr)==0) {
331 				LM_ERR("BUG: parse header failed\n");
332 				goto error;
333 			}
334 			foo.s[foo.len] = bar;
335 			ha->ival = hdr.type;
336 			if (hdr.type==HDR_OTHER_T || ha->title.s==0) {
337 				/* duplicate hdr name */
338 				ha->sval.s = (char*)pkg_malloc(foo.len+1);
339 				if (ha->sval.s==0) {
340 					PKG_MEM_ERROR;
341 					goto error;
342 				}
343 				memcpy( ha->sval.s, foo.s, foo.len);
344 				ha->sval.len = foo.len;
345 				ha->sval.s[ha->sval.len] = 0;
346 				if (ha->title.s==0)
347 					ha->title = ha->sval;
348 			}
349 		} else {
350 			/* element is MSG */
351 			if ( !(foo.len==ELEM_VAL_BODY_LEN &&
352 			!strncasecmp(ELEM_VAL_BODY,foo.s,foo.len)) ) {
353 				LM_ERR("unsupported value <%.*s> for msg type\n",foo.len,foo.s);
354 				goto error;
355 			}
356 			app->add_body = 1;
357 			pkg_free( ha );
358 			ha = 0;
359 		}
360 
361 		/* parse the element separator, if present */
362 		while( *s && isspace((int)*s) )  s++;
363 		if ( *s && *s!=';')
364 			goto parse_error;
365 		if (*s==';') {
366 			s++;
367 			while( *s && isspace((int)*s) )  s++;
368 			if (!*s)
369 				goto parse_error;
370 		}
371 
372 		/* link the element to tw_append structure */
373 		if (ha) {
374 			if (last==0) {
375 				last = app->elems = ha;
376 			} else {
377 				last->next = ha;
378 				last = ha;
379 			}
380 			ha = NULL;
381 		}
382 
383 	} /* end while */
384 
385 	print_tw_append( app );
386 	/* free the old string */
387 	pkg_free(val);
388 	return 0;
389 parse_error:
390 	LM_ERR("parse error in <%s> around position %ld\n",
391 			(char*)val, (long)(s-(char*)val));
392 error:
393 	if(ha) pkg_free(ha);
394 	return -1;
395 }
396 
397 
search_tw_append(char * name,int len)398 static struct tw_append *search_tw_append(char *name, int len)
399 {
400 	struct tw_append * app;
401 
402 	for( app=tw_appends ; app ; app=app->next )
403 		if (app->name.len==len && !strncasecmp(app->name.s,name,len) )
404 			return app;
405 	return 0;
406 }
407 
408 
fixup_t_write(void ** param,int param_no)409 int fixup_t_write( void** param, int param_no)
410 {
411 	struct tw_info *twi;
412 	char *s;
413 
414 	if (param_no==2) {
415 		twi = (struct tw_info*)pkg_malloc( sizeof(struct tw_info) );
416 		if (twi==0) {
417 			PKG_MEM_ERROR;
418 			return E_OUT_OF_MEM;
419 		}
420 		memset( twi, 0 , sizeof(struct tw_info));
421 		s = (char*)*param;
422 		twi->action.s = s;
423 		if ( (s=strchr(s,'/'))!=0) {
424 			twi->action.len = s - twi->action.s;
425 			if (twi->action.len==0) {
426 				LM_ERR("empty action name\n");
427 				pkg_free(twi);
428 				return E_CFG;
429 			}
430 			s++;
431 			if (*s==0) {
432 				LM_ERR("empty append name\n");
433 				pkg_free(twi);
434 				return E_CFG;
435 			}
436 			twi->append = search_tw_append( s, strlen(s));
437 			if (twi->append==0) {
438 				LM_ERR("unknown append name <%s>\n",s);
439 				pkg_free(twi);
440 				return E_CFG;
441 			}
442 		} else {
443 			twi->action.len = strlen(twi->action.s);
444 		}
445 		*param=(void*)twi;
446 	}
447 
448 	return 0;
449 }
450 
451 
init_twrite_sock(void)452 int init_twrite_sock(void)
453 {
454 	int flags;
455 
456 	sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
457 	if (sock == -1) {
458 		LM_ERR("unable to create socket: %s\n", strerror(errno));
459 		return -1;
460 	}
461 
462 	/* Turn non-blocking mode on */
463 	flags = fcntl(sock, F_GETFL);
464 	if (flags == -1){
465 		LM_ERR("fcntl failed: %s\n", strerror(errno));
466 		close(sock);
467 		return -1;
468 	}
469 
470 	if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
471 		LM_ERR("fcntl: set non-blocking failed: %s\n", strerror(errno));
472 		close(sock);
473 		return -1;
474 	}
475 	return 0;
476 }
477 
478 
init_twrite_lines()479 int init_twrite_lines()
480 {
481 	int i;
482 
483 	/* init the line table */
484 	for(i=0;i<TWRITE_PARAMS;i++) {
485 		iov_lines_eol[2*i].iov_base = 0;
486 		iov_lines_eol[2*i].iov_len = 0;
487 		iov_lines_eol[2*i+1] = eol;
488 	}
489 
490 	/* first line is the version - fill it now */
491 	eol_line_s(0)   = TWRITE_VERSION_S;
492 	eol_line_len(0) = TWRITE_VERSION_LEN;
493 
494 	return 0;
495 }
496 
497 
write_to_fifo(char * fifo,int cnt)498 static int inline write_to_fifo(char *fifo, int cnt )
499 {
500 	int   fd_fifo;
501 
502 	/* open FIFO file stream */
503 	if((fd_fifo = open(fifo,O_WRONLY | O_NONBLOCK)) == -1){
504 		switch(errno){
505 			case ENXIO:
506 				LM_ERR("cannot open fifo file - nobody listening for reading"
507 					" [%s] (%s)\n", fifo, strerror(errno));
508 				break;
509 			default:
510 				LM_ERR("failed to open [%s] fifo: %s\n", fifo, strerror(errno));
511 		}
512 		goto error;
513 	}
514 
515 	/* write now (unbuffered straight-down write) */
516 repeat:
517 	if (writev(fd_fifo, iov_lines_eol, 2*cnt)<0) {
518 		if (errno!=EINTR) {
519 			LM_ERR("writev failed: %s\n", strerror(errno));
520 			close(fd_fifo);
521 			goto error;
522 		} else {
523 			goto repeat;
524 		}
525 	}
526 	close(fd_fifo);
527 
528 	LM_DBG("write completed\n");
529 	return 1; /* OK */
530 
531 error:
532 	return -1;
533 }
534 
535 
add2buf(char * buf,char * end,char * title,int title_len,char * value,int value_len)536 static inline char* add2buf(char *buf, char *end, char *title, int title_len,
537 			char *value , int value_len)
538 {
539 	if (buf+title_len+value_len+2+1>=end)
540 		return 0;
541 	memcpy( buf, title, title_len);
542 	buf += title_len;
543 	*(buf++) = ':';
544 	*(buf++) = ' ';
545 	memcpy( buf, value, value_len);
546 	buf += value_len;
547 	*(buf++) = '\n';
548 	return buf;
549 }
550 
551 
append2buf(char * buf,int len,struct sip_msg * req,struct hdr_avp * ha)552 static inline char* append2buf( char *buf, int len, struct sip_msg *req,
553 			struct hdr_avp *ha)
554 {
555 	struct hdr_field *hdr;
556 	struct usr_avp   *avp;
557 	int_str          avp_val;
558 	int_str          avp_name;
559 	char  *end;
560 	str   foo;
561 	int   msg_parsed;
562 
563 	end = buf+len;
564 	msg_parsed = 0;
565 
566 	while(ha) {
567 		if (ha->type==ELEM_IS_AVP) {
568 			/* search for the AVP */
569 			if (ha->sval.s) {
570 				avp_name.s=ha->sval;
571 				avp = search_first_avp( AVP_NAME_STR, avp_name, &avp_val, 0);
572 				LM_DBG("AVP <%.*s>: %p\n",avp_name.s.len, avp_name.s.s, avp);
573 			} else {
574 				avp_name.n=ha->ival;
575 				avp = search_first_avp( 0, avp_name, &avp_val, 0);
576 				LM_DBG("AVP <%i>: %p\n",avp_name.n,avp);
577 			}
578 			if (avp) {
579 				if (avp->flags&AVP_VAL_STR) {
580 					buf=add2buf( buf, end, ha->title.s, ha->title.len,
581 						avp_val.s.s , avp_val.s.len);
582 					if (!buf)
583 						goto overflow_err;
584 				} else {
585 					foo.s=int2str( (unsigned long)avp_val.n, &foo.len);
586 					buf=add2buf( buf, end, ha->title.s, ha->title.len,
587 						foo.s , foo.len);
588 					if (!buf)
589 						goto overflow_err;
590 				}
591 			}
592 		} else if (ha->type==ELEM_IS_HDR) {
593 			/* parse the HDRs */
594 			if (!msg_parsed) {
595 				if (parse_headers( req, HDR_EOH_F, 0)!=0) {
596 					LM_ERR("parsing hdrs failed\n");
597 					goto error;
598 				}
599 				msg_parsed = 1;
600 			}
601 			/* search the HDR */
602 			if (ha->ival==HDR_OTHER_T) {
603 				for(hdr=req->headers;hdr;hdr=hdr->next)
604 					if (ha->sval.len==hdr->name.len &&
605 					strncasecmp( ha->sval.s, hdr->name.s, hdr->name.len)==0)
606 						break;
607 			} else {
608 				for(hdr=req->headers;hdr;hdr=hdr->next)
609 					if (ha->ival==hdr->type)
610 						break;
611 			}
612 			if (hdr) {
613 				trim_len( foo.len, foo.s, hdr->body);
614 				buf=add2buf( buf, end, ha->title.s, ha->title.len,
615 					foo.s , foo.len);
616 				if (!buf)
617 					goto overflow_err;
618 			}
619 		} else {
620 			LM_ERR("BUG: unknown element type %d\n", ha->type);
621 			goto error;
622 		}
623 
624 		ha = ha->next;
625 	}
626 
627 	return buf;
628 overflow_err:
629 	LM_ERR("overflow -> append exceeded %d len\n",len);
630 error:
631 	return 0;
632 }
633 
634 
assemble_msg(struct sip_msg * msg,struct tw_info * twi)635 static int assemble_msg(struct sip_msg* msg, struct tw_info *twi)
636 {
637 	static char     id_buf[IDBUF_LEN];
638 	static char     route_buffer[ROUTE_BUFFER_MAX];
639 	static char     append_buf[APPEND_BUFFER_MAX];
640 	static char     cmd_buf[CMD_BUFFER_MAX];
641 	static str      empty_param = STR_STATIC_INIT(".");
642 	unsigned int      hash_index, label;
643 	contact_body_t*   cb=0;
644 	contact_t*        c=0;
645 	name_addr_t       na;
646 	rr_t*             record_route;
647 	struct hdr_field* p_hdr;
648 	param_hooks_t     hooks;
649 	int               l;
650 	char*             s, fproxy_lr;
651 	int		  first_rr;
652 	str               route, next_hop, append, tmp_s, body, str_uri;
653 
654 	if(msg->first_line.type != SIP_REQUEST){
655 		LM_ERR("called for something else thena SIP request\n");
656 		goto error;
657 	}
658 
659 	/* parse all -- we will need every header field for a UAS */
660 	if ( parse_headers(msg, HDR_EOH_F, 0)==-1) {
661 		LM_ERR("parse_headers failed\n");
662 		goto error;
663 	}
664 
665 	/* find index and hash; (the transaction can be safely used due
666 	 * to refcounting till script completes) */
667 	if( t_get_trans_ident(msg,&hash_index,&label) == -1 ) {
668 		LM_ERR("assemble_msg: t_get_trans_ident failed\n");
669 		goto error;
670 	}
671 
672 	/* parse from header */
673 	if (msg->from==0 || (msg->from->parsed==0 && parse_from_header(msg)==-1)) {
674 		LM_ERR("while parsing <From:> header\n");
675 		goto error;
676 	}
677 
678 	/* parse the RURI (doesn't make any malloc) */
679 	msg->parsed_uri_ok = 0; /* force parsing */
680 	if (parse_sip_msg_uri(msg)<0) {
681 		LM_ERR("uri has not been parsed\n");
682 		goto error;
683 	}
684 
685 	/* parse contact header */
686 	str_uri.s = 0;
687 	str_uri.len = 0;
688 	if(msg->contact) {
689 		if (msg->contact->parsed==0 && parse_contact(msg->contact)==-1) {
690 			LM_ERR("error while parsing 'Contact' header\n");
691 			goto error;
692 		}
693 		cb = (contact_body_t*)msg->contact->parsed;
694 		if(cb && (c=cb->contacts)) {
695 			str_uri = c->uri;
696 			if (find_not_quoted(&str_uri,'<')) {
697 				parse_nameaddr(&str_uri,&na);
698 				str_uri = na.uri;
699 			}
700 		}
701 	}
702 
703 	/* str_uri is taken from caller's contact or from header
704 	 * for backwards compatibility with pre-3261 (from is already parsed)*/
705 	if(!str_uri.len || !str_uri.s)
706 		str_uri = get_from(msg)->uri;
707 
708 	/* parse Record-Route headers */
709 	route.s = s = route_buffer; route.len = 0;
710 	fproxy_lr = 0;
711 	next_hop = empty_param;
712 
713 	p_hdr = msg->record_route;
714 	if(p_hdr) {
715 		if (p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ) {
716 			LM_ERR("while parsing 'Record-Route' header\n");
717 			goto error;
718 		}
719 		record_route = (rr_t*)p_hdr->parsed;
720 	} else {
721 		record_route = 0;
722 	}
723 
724 	first_rr = 1;
725 
726 	if( record_route ) {
727 		if ( (tmp_s.s=find_not_quoted(&record_route->nameaddr.uri,';'))!=0 &&
728 		tmp_s.s+1!=record_route->nameaddr.uri.s+
729 		record_route->nameaddr.uri.len) {
730 			/* Parse all parameters */
731 			tmp_s.len = record_route->nameaddr.uri.len - (tmp_s.s-
732 				record_route->nameaddr.uri.s);
733 			if (parse_params( &tmp_s, CLASS_URI, &hooks,
734 			&record_route->params) < 0) {
735 				LM_ERR("error while parsing record route uri params\n");
736 				goto error;
737 			}
738 			fproxy_lr = (hooks.uri.lr != 0);
739 			LM_DBG("record_route->nameaddr.uri: %.*s\n",
740 				record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);
741 			if(fproxy_lr){
742 				first_rr = 0;
743 				LM_DBG("first proxy has loose routing.\n");
744 				copy_route(s,route.len,record_route->nameaddr.uri.s,
745 					record_route->nameaddr.uri.len);
746 			}
747 		}
748 		for(;p_hdr;p_hdr = p_hdr->next) {
749 			/* filter out non-RR hdr and empty hdrs */
750 			if( (p_hdr->type!=HDR_RECORDROUTE_T) || p_hdr->body.len==0)
751 				continue;
752 
753 			if(p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ){
754 				LM_ERR("while parsing 'Record-route' header\n");
755 				goto error;
756 			}
757 			for(record_route=p_hdr->parsed; record_route;
758 						record_route=record_route->next){
759 				LM_DBG("record_route->nameaddr.uri: <%.*s>\n",
760 						record_route->nameaddr.uri.len,
761 						record_route->nameaddr.uri.s);
762 				if (!first_rr) {
763 					copy_route(s,route.len,record_route->nameaddr.uri.s,
764 							record_route->nameaddr.uri.len);
765 				}
766 				first_rr=0;
767 			}
768 		}
769 
770 		if(!fproxy_lr){
771 			copy_route(s,route.len,str_uri.s,str_uri.len);
772 			str_uri = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
773 		} else {
774 			next_hop = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
775 		}
776 	}
777 
778 	LM_DBG("calculated route: %.*s\n", route.len,route.len ? route.s : "");
779 	LM_DBG("next r-uri: %.*s\n", str_uri.len,str_uri.len ? str_uri.s : "");
780 
781 	if ( REQ_LINE(msg).method_value==METHOD_INVITE ||
782 			REQ_LINE(msg).method_value==METHOD_INFO ||
783 			(twi->append && twi->append->add_body) ) {
784 		/* get body */
785 		if( (body.s = get_body(msg)) == 0 ){
786 			LM_ERR("get_body failed\n");
787 			goto error;
788 		}
789 		body.len = msg->len - (body.s - msg->buf);
790 	} else {
791 		body = empty_param;
792 	}
793 
794 	/* additional headers */
795 	append.s = s = append_buf;
796 	if (sizeof(flag_t)*2+12+1 >= APPEND_BUFFER_MAX) {
797 		LM_ERR("buffer overflow while copying optional header\n");
798 		goto error;
799 	}
800 	append_str(s,"P-MsgFlags: ",12);
801 	l = APPEND_BUFFER_MAX - (12+1); /* include trailing `\n'*/
802 
803 	if (int2reverse_hex(&s, &l, (int)msg->msg_flags) == -1) {
804 		LM_ERR("buffer overflow while copying optional header\n");
805 		goto error;
806 	}
807 	append_chr(s,'\n');
808 
809 	if ( twi->append && ((s=append2buf( s, APPEND_BUFFER_MAX-(s-append.s), msg,
810 	twi->append->elems))==0) )
811 		goto error;
812 
813 	/* body separator */
814 	append_chr(s,'.');
815 	append.len = s-append.s;
816 
817 	eol_line_s(1) = s = cmd_buf;
818 	if(twi->action.len+12 >= CMD_BUFFER_MAX){
819 		LM_ERR("buffer overflow while copying command name\n");
820 		goto error;
821 	}
822 	append_str(s,"sip_request.",12);
823 	append_str(s,twi->action.s, twi->action.len);
824 	eol_line_len(1) = s - (char*)eol_line_s(1);
825 
826 	eol_line(2,REQ_LINE(msg).method);     /* method type */
827 	eol_line(3,msg->parsed_uri.user);     /* user from r-uri */
828 	eol_line(4,msg->parsed_uri.host);     /* domain */
829 
830 	eol_line(5,msg->rcv.bind_address->address_str); /* dst ip */
831 
832 	eol_line(6,msg->rcv.dst_port==SIP_PORT ?
833 			empty_param : msg->rcv.bind_address->port_no_str); /* port */
834 
835 	/* r_uri ('Contact:' for next requests) */
836 	eol_line(7,msg->first_line.u.request.uri);
837 
838 	/* r_uri for subsequent requests */
839 	eol_line(8,str_uri.len?str_uri:empty_param);
840 
841 	eol_line(9,get_from(msg)->body);		/* from */
842 	eol_line(10,msg->to->body);			/* to */
843 	eol_line(11,msg->callid->body);		/* callid */
844 	eol_line(12,get_from(msg)->tag_value);	/* from tag */
845 	eol_line(13,get_to(msg)->tag_value);	/* to tag */
846 	eol_line(14,get_cseq(msg)->number);	/* cseq number */
847 
848 	eol_line_s(15)=id_buf;       /* hash:label */
849 	s = int2str(hash_index, &l);
850 	if (l+1>=IDBUF_LEN) {
851 		LM_ERR("too big hash\n");
852 		goto error;
853 	}
854 	memcpy(id_buf, s, l);
855 	id_buf[l]=':';
856 	eol_line_len(15)=l+1;
857 	s = int2str(label, &l);
858 	if (l+1+eol_line_len(15)>=IDBUF_LEN) {
859 		LM_ERR("too big label\n");
860 		goto error;
861 	}
862 	memcpy(id_buf+eol_line_len(15), s, l);
863 	eol_line_len(15) += l;
864 
865 	eol_line(16, route.len ? route : empty_param );
866 	eol_line(17, next_hop );
867 	eol_line(18, append );
868 	eol_line(19, body );
869 
870 	/* success */
871 	return 1;
872 error:
873 	/* 0 would lead to immediate script exit -- -1 returns
874 	 * with 'false' to script processing */
875 	return -1;
876 }
877 
878 
write_to_unixsock(char * sockname,int cnt)879 static int write_to_unixsock(char* sockname, int cnt)
880 {
881 	int len, e;
882 	struct sockaddr_un dest;
883 
884 	if (!sockname) {
885 		LM_ERR("Invalid parameter\n");
886 		return E_UNSPEC;
887 	}
888 
889 	len = strlen(sockname);
890 	if (len == 0) {
891 		LM_DBG("Error - empty socket name\n");
892 		return -1;
893 	} else if (len > 107) {
894 		LM_ERR("Socket name too long\n");
895 		return -1;
896 	}
897 
898 	memset(&dest, 0, sizeof(dest));
899 	dest.sun_family = PF_LOCAL;
900 	memcpy(dest.sun_path, sockname, len);
901 #ifdef HAVE_SOCKADDR_SA_LEN
902 	dest.sun_len = len;
903 #endif
904 
905 	e = connect(sock, (struct sockaddr*)&dest, SUN_LEN(&dest));
906 #ifdef HAVE_CONNECT_ECONNRESET_BUG
907 	/*
908 	 * Workaround for a nasty bug in BSD kernels dated back
909 	 * to the Berkeley days, so that can be found in many modern
910 	 * BSD-derived kernels. Workaround should be pretty harmless since
911 	 * in normal conditions connect(2) can never return ECONNRESET.
912 	 */
913 	if ((e == -1) && (errno == ECONNRESET))
914 		e = 0;
915 #endif
916 	if (e == -1) {
917 		LM_ERR("error in connect: %s\n", strerror(errno));
918 		return -1;
919 	}
920 
921 	if (tsend_dgram_ev(sock, iov_lines_eol, 2 * cnt,
922 			cfg_get(tm, tm_cfg, tm_unix_tx_timeout)) < 0) {
923 		LM_ERR("writev failed: %s\n", strerror(errno));
924 		return -1;
925 	}
926 
927 	return 0;
928 }
929 
930 
t_write_req(struct sip_msg * msg,char * vm_fifo,char * info)931 int t_write_req(struct sip_msg* msg, char* vm_fifo, char* info)
932 {
933 	if (assemble_msg(msg, (struct tw_info*)info) < 0) {
934 		LM_ERR("error int assemble_msg\n");
935 		return -1;
936 	}
937 
938 	if (write_to_fifo(vm_fifo, TWRITE_PARAMS) == -1) {
939 		LM_ERR("write_to_fifo failed\n");
940 		return -1;
941 	}
942 
943 	/* make sure that if voicemail does not initiate a reply
944 	 * timely, a SIP timeout will be sent out */
945 	if (add_blind_uac() == -1) {
946 		LM_ERR("add_blind failed\n");
947 		return -1;
948 	}
949 	return 1;
950 }
951 
952 
t_write_unix(struct sip_msg * msg,char * socket,char * info)953 int t_write_unix(struct sip_msg* msg, char* socket, char* info)
954 {
955 	if (assemble_msg(msg, (struct tw_info*)info) < 0) {
956 		LM_ERR("error in assemble_msg\n");
957 		return -1;
958 	}
959 
960 	if (write_to_unixsock(socket, TWRITE_PARAMS) == -1) {
961 		LM_ERR("write_to_unixsock failed\n");
962 		return -1;
963 	}
964 
965 	/* make sure that if voicemail does not initiate a reply
966 	 * timely, a SIP timeout will be sent out */
967 	if (add_blind_uac() == -1) {
968 		LM_ERR("add_blind failed\n");
969 		return -1;
970 	}
971 	return 1;
972 }
973