1 /**
2  * Copyright (C) 2012 Daniel-Constantin Mierla (asipto.com)
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * This file 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  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22 
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "../../core/dprint.h"
29 #include "../../core/ut.h"
30 #include "../../core/trim.h"
31 #include "../../core/mem/mem.h"
32 
33 #include "msrp_parser.h"
34 
35 typedef struct msrp_str_id {
36 	str sval;
37 	int ival;
38 } msrp_str_id_t;
39 
40 
41 static msrp_str_id_t _msrp_rtypes[] = {
42 	{ str_init("SEND"),      MSRP_REQ_SEND },
43 	{ str_init("AUTH"),      MSRP_REQ_AUTH },
44 	{ str_init("REPORT"),    MSRP_REQ_REPORT },
45 	{ {0, 0}, 0}
46 };
47 
48 
49 static msrp_str_id_t _msrp_htypes[] = {
50 	{ str_init("From-Path"),            MSRP_HDR_FROM_PATH },
51 	{ str_init("To-Path"),              MSRP_HDR_TO_PATH },
52 	{ str_init("Use-Path"),             MSRP_HDR_USE_PATH },
53 	{ str_init("Message-ID"),           MSRP_HDR_MESSAGE_ID },
54 	{ str_init("Byte-Range"),           MSRP_HDR_BYTE_RANGE },
55 	{ str_init("Status"),               MSRP_HDR_STATUS },
56 	{ str_init("Success-Report"),       MSRP_HDR_SUCCESS_REPORT },
57 	{ str_init("Content-Type"),         MSRP_HDR_CONTENT_TYPE },
58 	{ str_init("Authorization"),        MSRP_HDR_AUTH },
59 	{ str_init("WWW-Authenticate"),     MSRP_HDR_WWWAUTH },
60 	{ str_init("Authentication-Info"),  MSRP_HDR_AUTHINFO },
61 	{ str_init("Expires"),              MSRP_HDR_EXPIRES },
62 	{ {0, 0}, 0}
63 };
64 
65 
66 /* */
67 int msrp_fline_set_rtypeid(msrp_frame_t *mf);
68 int msrp_hdr_set_type(msrp_hdr_t *hdr);
69 
70 /**
71  *
72  */
msrp_parse_frame(msrp_frame_t * mf)73 int msrp_parse_frame(msrp_frame_t *mf)
74 {
75 	if(msrp_parse_fline(mf)<0)
76 	{
77 		LM_ERR("unable to parse first line\n");
78 		return -1;
79 	}
80 	if(msrp_parse_headers(mf)<0)
81 	{
82 		LM_ERR("unable to parse headers\n");
83 		return -1;
84 	}
85 	return 0;
86 }
87 
88 /**
89  *
90  */
msrp_parse_fline(msrp_frame_t * mf)91 int msrp_parse_fline(msrp_frame_t *mf)
92 {
93 	char *p;
94 	char *s;
95 
96 	mf->fline.buf.s = mf->buf.s;
97 	s = mf->buf.s;
98 	p =  q_memchr(mf->fline.buf.s, '\n', mf->buf.len);
99 	if(p==NULL) {
100 		LM_ERR("no end of line\n");
101 		return -1;
102 	}
103 	mf->fline.buf.len = p - mf->fline.buf.s + 1;
104 
105 	if(mf->fline.buf.len<10) {
106 		LM_ERR("too short for a valid first line [%.*s] (%d)\n",
107 				mf->fline.buf.len, mf->fline.buf.s, mf->fline.buf.len);
108 		return -1;
109 	}
110 	if(memcmp(mf->fline.buf.s, "MSRP ", 5)!=0) {
111 		LM_ERR("first line does not start with MSRP [%.*s] (%d)\n",
112 				mf->fline.buf.len, mf->fline.buf.s, mf->fline.buf.len);
113 		return -1;
114 	}
115 	mf->fline.protocol.s = mf->fline.buf.s;
116 	mf->fline.protocol.len = 4;
117 	s += 5;
118 	p =  q_memchr(s, ' ', mf->fline.buf.s + mf->fline.buf.len - s);
119 	/* eat whitespaces */
120 	while (p!=NULL && p==s) {
121 		s++;
122 		p =  q_memchr(s, ' ', mf->fline.buf.s + mf->fline.buf.len - s);
123 	}
124 	if(p==NULL) {
125 		LM_ERR("cannot find transaction id in first line [%.*s] (%d)\n",
126 				mf->fline.buf.len, mf->fline.buf.s, mf->fline.buf.len);
127 		return -1;
128 	}
129 	mf->fline.transaction.s = s;
130 	mf->fline.transaction.len = p - s;
131 	s = p+1;
132 	p =  q_memchr(s, ' ', mf->fline.buf.s + mf->fline.buf.len - s);
133 	/* eat whitespaces */
134 	while (p!=NULL && p==s) {
135 		s++;
136 		p =  q_memchr(s, ' ', mf->fline.buf.s + mf->fline.buf.len - s);
137 	}
138 	if(p==NULL) {
139 		if(s>=mf->fline.buf.s + mf->fline.buf.len - 2) {
140 			LM_ERR("cannot method in first line [%.*s] (%d)\n",
141 					mf->fline.buf.len, mf->fline.buf.s, mf->fline.buf.len);
142 			return -1;
143 		}
144 		mf->fline.rtype.s = s;
145 		mf->fline.rtype.len = mf->fline.buf.s + mf->fline.buf.len - s;
146 		trim(&mf->fline.rtype);
147 		mf->fline.msgtypeid = MSRP_REQUEST;
148 		goto done;
149 	}
150 	mf->fline.rtype.s = s;
151 	mf->fline.rtype.len = p - s;
152 	s = p+1;
153 	mf->fline.rtext.s = s;
154 	mf->fline.rtext.len = mf->fline.buf.s + mf->fline.buf.len - s;
155 	trim(&mf->fline.rtext);
156 	mf->fline.msgtypeid = MSRP_REPLY;
157 
158 done:
159 	if(msrp_fline_set_rtypeid(mf)<0)
160 	{
161 		LM_ERR("cannot set rtype-id in first line [%.*s] (%d)\n",
162 			mf->fline.buf.len, mf->fline.buf.s, mf->fline.buf.len);
163 		return -1;
164 	}
165 	LM_DBG("MSRP FLine: [%d] [%.*s] [%.*s] [%.*s] [%d] [%.*s]\n",
166 			mf->fline.msgtypeid,
167 			mf->fline.protocol.len, mf->fline.protocol.s,
168 			mf->fline.transaction.len, mf->fline.transaction.s,
169 			mf->fline.rtype.len, mf->fline.rtype.s,
170 			mf->fline.rtypeid,
171 			mf->fline.rtext.len, mf->fline.rtext.s);
172 	return 0;
173 }
174 
175 /**
176  *
177  */
msrp_fline_set_rtypeid(msrp_frame_t * mf)178 int msrp_fline_set_rtypeid(msrp_frame_t *mf)
179 {
180 	unsigned int i;
181 	if(mf->fline.msgtypeid==MSRP_REPLY)
182 	{
183 		if(str2int(&mf->fline.rtype, &i)<0)
184 		{
185 			LM_ERR("invalid status code [%.*s]\n",
186 					mf->fline.rtype.len, mf->fline.rtype.s);
187 			return -1;
188 		}
189 		mf->fline.rtypeid = MSRP_REQ_RPLSTART + i;
190 		return 0;
191 	}
192 	if(mf->fline.msgtypeid==MSRP_REQUEST)
193 	{
194 		for(i=0; _msrp_rtypes[i].sval.s!=NULL; i++)
195 		{
196 			if(mf->fline.rtype.len==_msrp_rtypes[i].sval.len
197 					&& strncmp(_msrp_rtypes[i].sval.s,
198 						mf->fline.rtype.s,
199 						_msrp_rtypes[i].sval.len)==0)
200 			{
201 				mf->fline.rtypeid = _msrp_rtypes[i].ival;
202 				return 0;
203 			}
204 		}
205 		return 0;
206 	}
207 	return -1;
208 }
209 
210 /**
211  *
212  */
msrp_parse_headers(msrp_frame_t * mf)213 int msrp_parse_headers(msrp_frame_t *mf)
214 {
215 	char *e; /* end of message */
216 	char *l; /* end of line */
217 	char *p; /* searched location */
218 	char *s; /* start for search */
219 	msrp_hdr_t *hdr;
220 	msrp_hdr_t *last;
221 	int fpath = 0; /* From path set */
222 	int tpath = 0; /* To path set */
223 	int any = 0; /* Any header set */
224 
225 	/* already parsed?!? */
226 	if(mf->headers != NULL)
227 		return 0;
228 
229 	last = NULL;
230 	mf->hbody.s = mf->fline.buf.s + mf->fline.buf.len;
231 	e = mf->buf.s + mf->buf.len;
232 	s = mf->hbody.s;
233 	p = s;
234 	while(p!=NULL)
235 	{
236 		l = q_memchr(s, '\n', e - s);
237 		if(l==NULL) {
238 			LM_ERR("broken msrp frame message\n");
239 			return -1;
240 		}
241 		p = q_memchr(s, ':', l - s);
242 		if(p==NULL)
243 		{
244 			/* line without ':' - end of headers */
245 			if(s[0]=='-')
246 			{
247 				mf->endline.len = 7 + mf->fline.transaction.len + 1 + 2;
248 				/* check if it is end-line (i.e., no msg body) */
249 				if((l-s+1 == mf->endline.len)
250 						&& strncmp(s, "-------", 7)==0
251 						&& strncmp(s+7, mf->fline.transaction.s,
252 							mf->fline.transaction.len)==0)
253 				{
254 					mf->hbody.len = s - mf->hbody.s;
255 					mf->endline.s = s;
256 					goto ateoh;
257 				}
258 				mf->endline.len = 0;
259 				LM_ERR("mismatch msrp frame message eoh endline\n");
260 				return -1;
261 			} else if (s[0]=='\r' || s[0]=='\n') {
262 				mf->hbody.len = s - mf->hbody.s;
263 				mf->mbody.s = l + 1;
264 				goto ateoh;
265 			}
266 			LM_ERR("broken msrp frame message eoh\n");
267 			return -1;
268 		}
269 		/* new header */
270 		hdr = (msrp_hdr_t*)pkg_malloc(sizeof(msrp_hdr_t));
271 		if(hdr==NULL)
272 		{
273 			LM_ERR("no more pkg\n");
274 			return -1;
275 		}
276 		memset(hdr, 0, sizeof(msrp_hdr_t));
277 		hdr->buf.s = s;
278 		hdr->buf.len = l - s + 1;
279 		hdr->name.s = s;
280 		hdr->name.len = p - s;
281 		hdr->body.s = p + 1;
282 		hdr->body.len = l - p - 1;
283 		trim(&hdr->body);
284 
285 		if(last==NULL)
286 		{
287 			mf->headers = hdr;
288 			last = hdr;
289 		} else {
290 			last->next = hdr;
291 			last = hdr;
292 		}
293 		msrp_hdr_set_type(hdr);
294 
295 		/* Checking for well-formed MSRP rfc4975 messages */
296 		if (hdr->htype == MSRP_HDR_TO_PATH) {
297 			if (tpath) {
298 				LM_ERR("broken msrp frame message, Multiple To-Path not allowed.\n");
299 				return -1;
300 			} else if (fpath || any) {
301 				LM_ERR("broken msrp frame message, To-Path must be the first header.\n");
302 				return -1;
303 			} else {
304 				tpath = 1;
305 			}
306 		} else if (hdr->htype == MSRP_HDR_FROM_PATH) {
307 			if (fpath) {
308 				LM_ERR("broken msrp frame message, Multiple From-Path not allowed.\n");
309 				return -1;
310 			} else if (!tpath || any) {
311 				LM_ERR("broken msrp frame message, From-Path must be after To-Path.\n");
312 				return -1;
313 			} else {
314 				fpath = 1;
315 			}
316 		} else {
317 			if (!tpath || !fpath) {
318 				LM_ERR("broken msrp frame message, To-Path and From-Path must be defined before any header.\n");
319 				return -1;
320 			} else {
321 				any = 1;
322 			}
323 		}
324 
325 		LM_DBG("MSRP Header: (%p) [%.*s] [%d] [%.*s]\n",
326 				hdr, hdr->name.len, hdr->name.s, hdr->htype,
327 				hdr->body.len, hdr->body.s);
328 		s = l + 1;
329 	}
330 
331 	if (!tpath || !fpath) {
332 		LM_ERR("broken msrp frame message, To-Path and From-Path must be defined.\n");
333 		return -1;
334 	}
335 
336 ateoh:
337 	if(mf->mbody.s!=NULL)
338 	{
339 		/* last header must be Content-Type */
340 
341 		/* get now body.len and endline */
342 		mf->endline.len = 7 + mf->fline.transaction.len + 1 + 2;
343 		mf->endline.s = e - mf->endline.len;
344 		s = mf->endline.s;
345 		if(s[-1]!='\n')
346 		{
347 			LM_ERR("broken msrp frame message body endline\n");
348 			return -1;
349 		}
350 		if(strncmp(s, "-------", 7)==0
351 				&& strncmp(s+7, mf->fline.transaction.s,
352 				mf->fline.transaction.len)==0)
353 		{
354 			mf->mbody.len = s - mf->mbody.s;
355 			LM_DBG("MSRP Body: [%d] [[\n%.*s\n]]\n",
356 					mf->mbody.len, mf->mbody.len, mf->mbody.s);
357 			return 0;
358 		}
359 		LM_ERR("mismatch msrp frame message body endline\n");
360 		return -1;
361 
362 	}
363 	return 0;
364 }
365 
366 /**
367  *
368  */
msrp_hdr_set_type(msrp_hdr_t * hdr)369 int msrp_hdr_set_type(msrp_hdr_t *hdr)
370 {
371 	int i;
372 	if(hdr==NULL)
373 		return -1;
374 
375 	for(i=0; _msrp_htypes[i].sval.s!=NULL; i++)
376 	{
377 		if(hdr->name.len==_msrp_htypes[i].sval.len
378 				&& strncmp(_msrp_htypes[i].sval.s,
379 					hdr->name.s,
380 					_msrp_htypes[i].sval.len)==0)
381 		{
382 			hdr->htype = _msrp_htypes[i].ival;
383 			return 0;
384 		}
385 	}
386 	return 1;
387 }
388 
389 /**
390  *
391  */
msrp_destroy_frame(msrp_frame_t * mf)392 void msrp_destroy_frame(msrp_frame_t *mf)
393 {
394 	msrp_hdr_t *hdr;
395 	msrp_hdr_t *nxt;
396 
397 	if(mf==NULL || mf->headers==NULL)
398 		return;
399 
400 	hdr = mf->headers;
401 	while(hdr!=NULL)
402 	{
403 		nxt = hdr->next;
404 		if(hdr->parsed.flags&MSRP_DATA_SET)
405 		{
406 			if(hdr->parsed.free_fn)
407 			{
408 				hdr->parsed.free_fn(hdr->parsed.data);
409 			}
410 		}
411 		pkg_free(hdr);
412 		hdr = NULL;
413 		hdr = nxt;
414 	}
415 
416 	return;
417 }
418 
419 /**
420  *
421  */
msrp_free_frame(msrp_frame_t * mf)422 void msrp_free_frame(msrp_frame_t *mf)
423 {
424 	msrp_destroy_frame(mf);
425 	pkg_free(mf);
426 	return;
427 }
428 
429 /**
430  *
431  */
msrp_parse_uri(char * start,int len,msrp_uri_t * uri)432 int msrp_parse_uri(char *start, int len, msrp_uri_t *uri)
433 {
434 	char *e;
435 	char *l;
436 	char *p;
437 	char *s;
438 	str *hook;
439 
440 	if(start==NULL || uri==NULL || len<8)
441 	{
442 		LM_ERR("invalid parameters\n");
443 		return -1;
444 	}
445 
446 	memset(uri, 0, sizeof(msrp_uri_t));
447 	e = start + len;
448 	s = start;
449 	uri->buf.s = s;
450 	uri->scheme.s = s;
451 
452 	if(strncasecmp(s, "msrp://", 7)==0) {
453 		uri->scheme.len = 4;
454 		uri->scheme_no = MSRP_SCHEME_MSRP;
455 		s += 7;
456 	} else if(strncasecmp(s, "msrps://", 8)==0) {
457 		uri->scheme.len = 5;
458 		uri->scheme_no = MSRP_SCHEME_MSRPS;
459 		s += 8;
460 	} else {
461 		LM_ERR("invalid scheme in [%.*s]\n", len, start);
462 		goto error;
463 	}
464 
465 	p = q_memchr(s, '@', e - s);
466 	if(p!=NULL)
467 	{
468 		l = q_memchr(s, ';', e - s);
469 		if(l==NULL || p<l)
470 		{
471 			/* user info part */
472 			uri->userinfo.s = s;
473 			uri->userinfo.len = p - s;
474 			uri->user.s = s;
475 			l = q_memchr(uri->userinfo.s, ';', uri->userinfo.len);
476 			if(l!=NULL)
477 			{
478 				uri->user.len = l - uri->user.s;
479 			} else {
480 				l = q_memchr(uri->userinfo.s, ':', uri->userinfo.len);
481 				if(l!=NULL)
482 				{
483 					uri->user.len = l - uri->user.s;
484 				} else {
485 					uri->user.len = uri->userinfo.len;
486 				}
487 			}
488 		}
489 		s = p + 1;
490 		if(s>=e) goto error;
491 	}
492 	hook = &uri->host;
493 	hook->s = s;
494 	if(*s == '[')
495 	{
496 		/* IPv6 */
497 		p = q_memchr(s, ']', e - s);
498 		if(p == NULL)
499 		{
500 			goto error;
501 		}
502 		s = p + 1;
503 		hook->len = s - hook->s;
504 	}
505 	p = q_memchr(s, ':', e - s);
506 	if(p!=NULL)
507 	{
508 		if(hook->len == 0)
509 		{
510 			/* host len was not set yet */
511 			hook->len = p - hook->s;
512 		}
513 		hook = &uri->port;
514 		s = p+1;
515 		if(s>=e) goto error;
516 	}
517 	hook->s = s;
518 	p = q_memchr(s, '/', e - s);
519 	if(p!=NULL)
520 	{
521 		hook->len = p - hook->s;
522 		hook = &uri->session;
523 		s = p+1;
524 		if(s>=e) goto error;
525 	}
526 	hook->s = s;
527 	p = q_memchr(s, ';', e - s);
528 	if(p!=NULL)
529 	{
530 		hook->len = p - hook->s;
531 		hook = &uri->params;
532 		s = p+1;
533 		if(s>=e) goto error;
534 	}
535 	hook->s = s;
536 	hook->len = e - hook->s;
537 	trim(hook);
538 
539 	if(uri->host.len<=0)
540 	{
541 		LM_ERR("bad host part in [%.*s] at [%ld]\n",
542 				len, start, (long)(s - start));
543 		goto error;
544 	}
545 	if(uri->port.len <= 0)
546 	{
547 		uri->port_no = 0;
548 	} else {
549 		str2sint(&uri->port, &uri->port_no);
550 		if(uri->port_no<1 || uri->port_no > ((1<<16)-1))
551 		{
552 			LM_ERR("bad port part in [%.*s] at [%ld]\n",
553 					len, start, (long)(s - start));
554 			goto error;
555 		}
556 	}
557 	if(uri->params.len > 0)
558 	{
559 		uri->proto.s = uri->params.s;
560 		if(uri->params.len > 3 && strncasecmp(uri->params.s, "tcp", 3)==0) {
561 			uri->proto.len = 3;
562 			uri->proto_no = MSRP_PROTO_TCP;
563 		} else if (uri->params.len > 2 && strncasecmp(uri->params.s, "ws", 2)==0) {
564 			uri->proto.len = 2;
565 			uri->proto_no = MSRP_PROTO_WS;
566 		} else {
567 			p = q_memchr(uri->params.s, ';', uri->params.len);
568 			if(p!=NULL) {
569 				uri->proto.len = p - uri->proto.s;
570 				uri->params.len = uri->params.s + uri->params.len - p - 1;
571 				uri->params.s = p + 1;
572 			} else {
573 				uri->proto.len = uri->params.len;
574 				uri->params.s = NULL;
575 				uri->params.len = 0;
576 			}
577 		}
578 	}
579 
580 	LM_DBG("MSRP URI: [%.*s] [%.*s] [%.*s] [%.*s] [%.*s] [%.*s] [%.*s]\n",
581 			uri->scheme.len, uri->scheme.s,
582 			uri->user.len, (uri->user.s)?uri->user.s:"",
583 			uri->host.len, uri->host.s,
584 			uri->port.len, (uri->port.s)?uri->port.s:"",
585 			uri->session.len, (uri->session.s)?uri->session.s:"",
586 			uri->proto.len, (uri->proto.s)?uri->proto.s:"",
587 			uri->params.len, (uri->params.s)?uri->params.s:"");
588 	return 0;
589 
590 error:
591 	LM_ERR("parsing error in [%.*s] at [%ld]\n",
592 			len, start, (long int)(s - start));
593 	memset(uri, 0, sizeof(msrp_uri_t));
594 	return -1;
595 }
596 
597 /**
598  *
599  */
msrp_get_hdr_by_id(msrp_frame_t * mf,int hdrid)600 msrp_hdr_t *msrp_get_hdr_by_id(msrp_frame_t *mf, int hdrid)
601 {
602 	msrp_hdr_t *hdr;
603 	for(hdr=mf->headers; hdr; hdr=hdr->next)
604 		if(hdr->htype==hdrid)
605 			return hdr;
606 	return NULL;
607 }
608 
609 
610 /**
611  *
612  */
msrp_explode_str(str ** arr,str * in,str * del)613 int msrp_explode_str(str **arr, str *in, str *del)
614 {
615 	str *larr;
616 	int i;
617 	int j;
618 	int k;
619 	int n;
620 
621 	/* Find number of strings */
622 	n = 0;
623 	for(i=0; i<in->len; i++)
624 	{
625 		for(j=0; j<del->len; j++)
626 		{
627 			if(in->s[i]==del->s[j])
628 			{
629 				n++;
630 				break;
631 			}
632 		}
633 	}
634 	n++;
635 
636 	larr = pkg_malloc(n * sizeof(str));
637 	if(larr==NULL)
638 	{
639 		LM_ERR("no more pkg\n");
640 		return -1;
641 	}
642 	memset(larr, 0, n * sizeof(str));
643 
644 	k = 0;
645 	if(n==1)
646 	{
647 		larr[k].s = in->s;
648 		larr[k].len = in->len;
649 		*arr = larr;
650 		return n;
651 	}
652 
653 	larr[k].s = in->s;
654 	for(i=0; i<in->len; i++)
655 	{
656 		for(j=0; j<del->len; j++)
657 		{
658 			if(in->s[i]==del->s[j])
659 			{
660 				if(k<n)
661 					larr[k].len = in->s + i - larr[k].s;
662 				k++;
663 				if(k<n)
664 					larr[k].s = in->s + i + 1;
665 				break;
666 			}
667 		}
668 	}
669 	if(k<n)
670 		larr[k].len = in->s + i - larr[k].s;
671 
672 	*arr = larr;
673 
674 	return n;
675 }
676 
677 /**
678  *
679  */
msrp_explode_strz(str ** arr,str * in,char * del)680 int msrp_explode_strz(str **arr, str *in, char *del)
681 {
682 	str s;
683 
684 	s.s = del;
685 	s.len = strlen(s.s);
686 	return msrp_explode_str(arr, in, &s);
687 }
688 
msrp_str_array_destroy(void * data)689 void msrp_str_array_destroy(void *data)
690 {
691 	str_array_t *arr;
692 	if(data==NULL)
693 		return;
694 	arr = (str_array_t*)data;
695 	if(arr->list!=NULL)
696 			pkg_free(arr->list);
697 	pkg_free(arr);
698 }
699 
700 /**
701  *
702  */
msrp_parse_hdr_uri_list(msrp_hdr_t * hdr)703 int msrp_parse_hdr_uri_list(msrp_hdr_t *hdr)
704 {
705 	str_array_t *arr;
706 	str s;
707 
708 	arr = pkg_malloc(sizeof(str_array_t));
709 	if(arr==NULL)
710 	{
711 		LM_ERR("no more pkg\n");
712 		return -1;
713 	}
714 	memset(arr, 0, sizeof(str_array_t));
715 
716 	s = hdr->body;
717 	trim(&s);
718 	arr->size = msrp_explode_strz(&arr->list, &s, " ");
719 	hdr->parsed.flags |= MSRP_DATA_SET;
720 	hdr->parsed.free_fn = msrp_str_array_destroy;
721 	hdr->parsed.data = arr;
722 	return 0;
723 }
724 
725 /**
726  *
727  */
msrp_parse_hdr_from_path(msrp_frame_t * mf)728 int msrp_parse_hdr_from_path(msrp_frame_t *mf)
729 {
730 	msrp_hdr_t *hdr;
731 
732 	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
733 	if(hdr==NULL)
734 		return -1;
735 	if(hdr->parsed.flags&MSRP_DATA_SET)
736 		return 0;
737 	return msrp_parse_hdr_uri_list(hdr);
738 }
739 
740 /**
741  *
742  */
msrp_parse_hdr_to_path(msrp_frame_t * mf)743 int msrp_parse_hdr_to_path(msrp_frame_t *mf)
744 {
745 	msrp_hdr_t *hdr;
746 
747 	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
748 	if(hdr==NULL)
749 		return -1;
750 	if(hdr->parsed.flags&MSRP_DATA_SET)
751 		return 0;
752 	return msrp_parse_hdr_uri_list(hdr);
753 }
754 
755 /**
756  *
757  */
msrp_parse_hdr_expires(msrp_frame_t * mf)758 int msrp_parse_hdr_expires(msrp_frame_t *mf)
759 {
760 	msrp_hdr_t *hdr;
761 	str hbody;
762 	int expires;
763 
764 	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_EXPIRES);
765 	if(hdr==NULL)
766 		return -1;
767 	if(hdr->parsed.flags&MSRP_DATA_SET)
768 		return 0;
769 	hbody = hdr->body;
770 	trim(&hbody);
771 	if(str2sint(&hbody, &expires)<0) {
772 		LM_ERR("invalid expires value\n");
773 		return -1;
774 	}
775 	hdr->parsed.flags |= MSRP_DATA_SET;
776 	hdr->parsed.free_fn = NULL;
777 	hdr->parsed.data = (void*)(long)expires;
778 
779 	return 0;
780 }
781 
782 /**
783  *
784  */
msrp_frame_get_first_from_path(msrp_frame_t * mf,str * sres)785 int msrp_frame_get_first_from_path(msrp_frame_t *mf, str *sres)
786 {
787 	str s = {0};
788 	msrp_hdr_t *hdr;
789 	str_array_t *sar;
790 
791 	if(msrp_parse_hdr_from_path(mf)<0)
792 		return -1;
793 	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
794 	if(hdr==NULL)
795 		return -1;
796 	sar = (str_array_t*)hdr->parsed.data;
797 	s = sar->list[sar->size-1];
798 	trim(&s);
799 	*sres = s;
800 	return 0;
801 }
802 
803 /**
804  *
805  */
msrp_frame_get_expires(msrp_frame_t * mf,int * expires)806 int msrp_frame_get_expires(msrp_frame_t *mf, int *expires)
807 {
808 	msrp_hdr_t *hdr;
809 
810 	if(msrp_parse_hdr_expires(mf)<0)
811 		return -1;
812 	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_AUTH);
813 	if(hdr==NULL)
814 		return -1;
815 	*expires = (int)(long)hdr->parsed.data;
816 	return 0;
817 }
818 
819 /**
820  *
821  */
msrp_frame_get_sessionid(msrp_frame_t * mf,str * sres)822 int msrp_frame_get_sessionid(msrp_frame_t *mf, str *sres)
823 {
824 	str s = {0};
825 	msrp_hdr_t *hdr;
826 	str_array_t *sar;
827 	msrp_uri_t uri;
828 
829 	if(msrp_parse_hdr_to_path(mf)<0)
830 		return -1;
831 	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
832 	if(hdr==NULL)
833 		return -1;
834 	sar = (str_array_t*)hdr->parsed.data;
835 	s = sar->list[0];
836 	trim(&s);
837 	if(msrp_parse_uri(s.s, s.len, &uri)<0 || uri.session.len<=0)
838 		return -1;
839 	s = uri.session;
840 	trim(&s);
841 	*sres = s;
842 
843 	return 0;
844 }
845 
846