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