int msrp_parse_headers(msrp_frame_t *mf) { char *e; /* end of message */ char *l; /* end of line */ char *p; /* searched location */ char *s; /* start for search */ msrp_hdr_t *hdr; msrp_hdr_t *last; /* already parsed?!? */ if(mf->headers != NULL) return 0; last = NULL; mf->hbody.s = mf->fline.buf.s + mf->fline.buf.len; e = mf->buf.s + mf->buf.len; s = mf->hbody.s; p = s; while(p!=NULL) { l = q_memchr(s, '\n', e - s); if(l==NULL) { LM_ERR("broken msrp frame message\n"); return -1; } p = q_memchr(s, ':', l - s); if(p==NULL) { /* line without ':' - end of headers */ if(s[0]=='-') { mf->endline.len = 7 + mf->fline.transaction.len + 1 + 2; /* check if it is end-line (i.e., no msg body) */ if((l-s+1 == mf->endline.len) && strncmp(s, "-------", 7)==0 && strncmp(s+7, mf->fline.transaction.s, mf->fline.transaction.len)==0) { mf->hbody.len = s - mf->hbody.s; mf->endline.s = s; goto ateoh; } mf->endline.len = 0; LM_ERR("mismatch msrp frame message eoh endline\n"); return -1; } else if (s[0]=='\r' || s[0]=='\n') { mf->hbody.len = s - mf->hbody.s; mf->mbody.s = l + 1; goto ateoh; } LM_ERR("broken msrp frame message eoh\n"); return -1; } /* new header */ hdr = (msrp_hdr_t*)pkg_malloc(sizeof(msrp_hdr_t)); if(hdr==NULL) { LM_ERR("no more pkg\n"); return -1; } memset(hdr, 0, sizeof(msrp_hdr_t)); hdr->buf.s = s; hdr->buf.len = l - s + 1; hdr->name.s = s; hdr->name.len = p - s; hdr->body.s = p + 1; hdr->body.len = l - p - 1; trim(&hdr->body); if(last==NULL) { mf->headers = hdr; last = hdr; } else { last->next = hdr; last = hdr; } msrp_hdr_set_type(hdr); LM_DBG("MSRP Header: (%p) [%.*s] [%d] [%.*s]\n", hdr, hdr->name.len, hdr->name.s, hdr->htype, hdr->body.len, hdr->body.s); s = l + 1; } ateoh: if(mf->mbody.s!=NULL) { /* last header must be Content-Type */ /* get now body.len and endline */ mf->endline.len = 7 + mf->fline.transaction.len + 1 + 2; mf->endline.s = e - mf->endline.len; s = mf->endline.s; if(s[-1]!='\n') { LM_ERR("broken msrp frame message body endline\n"); return -1; } if(strncmp(s, "-------", 7)==0 && strncmp(s+7, mf->fline.transaction.s, mf->fline.transaction.len)==0) { mf->mbody.len = s - mf->mbody.s; LM_DBG("MSRP Body: [%d] [[\n%.*s\n]]\n", mf->mbody.len, mf->mbody.len, mf->mbody.s); return 0; } LM_ERR("mismatch msrp frame message body endline\n"); return -1; } return 0; }
int msrp_parse_headers(msrp_frame_t *mf) { char *e; /* end of message */ char *l; /* end of line */ char *p; /* searched location */ char *s; /* start for search */ msrp_hdr_t *hdr; msrp_hdr_t *last; int fpath = 0; /* From path set */ int tpath = 0; /* To path set */ int any = 0; /* Any header set */ /* already parsed?!? */ if(mf->headers != NULL) return 0; last = NULL; mf->hbody.s = mf->fline.buf.s + mf->fline.buf.len; e = mf->buf.s + mf->buf.len; s = mf->hbody.s; p = s; while(p!=NULL) { l = q_memchr(s, '\n', e - s); if(l==NULL) { LM_ERR("broken msrp frame message\n"); return -1; } p = q_memchr(s, ':', l - s); if(p==NULL) { /* line without ':' - end of headers */ if(s[0]=='-') { mf->endline.len = 7 + mf->fline.transaction.len + 1 + 2; /* check if it is end-line (i.e., no msg body) */ if((l-s+1 == mf->endline.len) && strncmp(s, "-------", 7)==0 && strncmp(s+7, mf->fline.transaction.s, mf->fline.transaction.len)==0) { mf->hbody.len = s - mf->hbody.s; mf->endline.s = s; goto ateoh; } mf->endline.len = 0; LM_ERR("mismatch msrp frame message eoh endline\n"); return -1; } else if (s[0]=='\r' || s[0]=='\n') { mf->hbody.len = s - mf->hbody.s; mf->mbody.s = l + 1; goto ateoh; } LM_ERR("broken msrp frame message eoh\n"); return -1; } /* new header */ hdr = (msrp_hdr_t*)pkg_malloc(sizeof(msrp_hdr_t)); if(hdr==NULL) { LM_ERR("no more pkg\n"); return -1; } memset(hdr, 0, sizeof(msrp_hdr_t)); hdr->buf.s = s; hdr->buf.len = l - s + 1; hdr->name.s = s; hdr->name.len = p - s; hdr->body.s = p + 1; hdr->body.len = l - p - 1; trim(&hdr->body); if(last==NULL) { mf->headers = hdr; last = hdr; } else { last->next = hdr; last = hdr; } msrp_hdr_set_type(hdr); /* Checking for well-formed MSRP rfc4975 messages */ if (hdr->htype == MSRP_HDR_TO_PATH) { if (tpath) { LM_ERR("broken msrp frame message, Multiple To-Path not allowed.\n"); return -1; } else if (fpath || any) { LM_ERR("broken msrp frame message, To-Path must be the first header.\n"); return -1; } else { tpath = 1; } } else if (hdr->htype == MSRP_HDR_FROM_PATH) { if (fpath) { LM_ERR("broken msrp frame message, Multiple From-Path not allowed.\n"); return -1; } else if (!tpath || any) { LM_ERR("broken msrp frame message, From-Path must be after To-Path.\n"); return -1; } else { fpath = 1; } } else { if (!tpath || !fpath) { LM_ERR("broken msrp frame message, To-Path and From-Path must be defined before any header.\n"); return -1; } else { any = 1; } } LM_DBG("MSRP Header: (%p) [%.*s] [%d] [%.*s]\n", hdr, hdr->name.len, hdr->name.s, hdr->htype, hdr->body.len, hdr->body.s); s = l + 1; } if (!tpath || !fpath) { LM_ERR("broken msrp frame message, To-Path and From-Path must be defined.\n"); return -1; } ateoh: if(mf->mbody.s!=NULL) { /* last header must be Content-Type */ /* get now body.len and endline */ mf->endline.len = 7 + mf->fline.transaction.len + 1 + 2; mf->endline.s = e - mf->endline.len; s = mf->endline.s; if(s[-1]!='\n') { LM_ERR("broken msrp frame message body endline\n"); return -1; } if(strncmp(s, "-------", 7)==0 && strncmp(s+7, mf->fline.transaction.s, mf->fline.transaction.len)==0) { mf->mbody.len = s - mf->mbody.s; LM_DBG("MSRP Body: [%d] [[\n%.*s\n]]\n", mf->mbody.len, mf->mbody.len, mf->mbody.s); return 0; } LM_ERR("mismatch msrp frame message body endline\n"); return -1; } return 0; }