|
@@ -0,0 +1,456 @@
|
|
|
|
+/**
|
|
|
|
+ * $Id$
|
|
|
|
+ *
|
|
|
|
+ * Copyright (C) 2012 Daniel-Constantin Mierla (asipto.com)
|
|
|
|
+ *
|
|
|
|
+ * This file is part of Kamailio, a free SIP server.
|
|
|
|
+ *
|
|
|
|
+ * This file is free software; you can redistribute it and/or modify
|
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
|
+ * (at your option) any later version
|
|
|
|
+ *
|
|
|
|
+ *
|
|
|
|
+ * This file is distributed in the hope that it will be useful,
|
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+ * GNU General Public License for more details.
|
|
|
|
+ *
|
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
|
+ * along with this program; if not, write to the Free Software
|
|
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <unistd.h>
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+
|
|
|
|
+#include "../../dprint.h"
|
|
|
|
+#include "../../trim.h"
|
|
|
|
+#include "../../ut.h"
|
|
|
|
+#include "../../pvapi.h"
|
|
|
|
+
|
|
|
|
+#include "msrp_parser.h"
|
|
|
|
+#include "msrp_vars.h"
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+int pv_parse_msrp_name(pv_spec_t *sp, str *in)
|
|
|
|
+{
|
|
|
|
+ if(sp==NULL || in==NULL || in->len<=0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ switch(in->len)
|
|
|
|
+ {
|
|
|
|
+ case 3:
|
|
|
|
+ if(strncmp(in->s, "buf", 3)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 1;
|
|
|
|
+ else goto error;
|
|
|
|
+ break;
|
|
|
|
+ case 4:
|
|
|
|
+ if(strncmp(in->s, "body", 4)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 2;
|
|
|
|
+ else if(strncmp(in->s, "code", 4)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 3;
|
|
|
|
+ else if(strncmp(in->s, "hdrs", 4)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 4;
|
|
|
|
+ else goto error;
|
|
|
|
+ break;
|
|
|
|
+ case 5:
|
|
|
|
+ if(strncmp(in->s, "msgid", 5)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 5;
|
|
|
|
+ else goto error;
|
|
|
|
+ case 6:
|
|
|
|
+ if(strncmp(in->s, "method", 6)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 6;
|
|
|
|
+ else if(strncmp(in->s, "buflen", 6)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 7;
|
|
|
|
+ else if(strncmp(in->s, "sessid", 6)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 8;
|
|
|
|
+ else if(strncmp(in->s, "reason", 6)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 9;
|
|
|
|
+ else if(strncmp(in->s, "crthop", 6)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 12;
|
|
|
|
+ else goto error;
|
|
|
|
+ break;
|
|
|
|
+ case 7:
|
|
|
|
+ if(strncmp(in->s, "bodylen", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 10;
|
|
|
|
+ else if(strncmp(in->s, "transid", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 11;
|
|
|
|
+ else if(strncmp(in->s, "prevhop", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 13;
|
|
|
|
+ else if(strncmp(in->s, "nexthop", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 14;
|
|
|
|
+ else if(strncmp(in->s, "lasthop", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 15;
|
|
|
|
+ else if(strncmp(in->s, "srcaddr", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 19;
|
|
|
|
+ else if(strncmp(in->s, "srcsock", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 20;
|
|
|
|
+ else goto error;
|
|
|
|
+ break;
|
|
|
|
+ case 8:
|
|
|
|
+ if(strncmp(in->s, "firsthop", 8)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 16;
|
|
|
|
+ else if(strncmp(in->s, "prevhops", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 17;
|
|
|
|
+ else if(strncmp(in->s, "nexthops", 7)==0)
|
|
|
|
+ sp->pvp.pvn.u.isname.name.n = 18;
|
|
|
|
+ else goto error;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ /* max is 20 */
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+ sp->pvp.pvn.type = PV_NAME_INTSTR;
|
|
|
|
+ sp->pvp.pvn.u.isname.type = 0;
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+error:
|
|
|
|
+ LM_ERR("unknown PV msrp name %.*s\n", in->len, in->s);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+int pv_get_msrp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res)
|
|
|
|
+{
|
|
|
|
+ msrp_frame_t *mf;
|
|
|
|
+ msrp_hdr_t *hdr;
|
|
|
|
+ str_array_t *sar;
|
|
|
|
+ msrp_uri_t uri;
|
|
|
|
+ str s;
|
|
|
|
+ char *p;
|
|
|
|
+
|
|
|
|
+ mf = msrp_get_current_frame();
|
|
|
|
+ if(mf==NULL || param==NULL)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ sar = NULL;
|
|
|
|
+ hdr = NULL;
|
|
|
|
+
|
|
|
|
+ switch(param->pvn.u.isname.name.n)
|
|
|
|
+ {
|
|
|
|
+ case 1:
|
|
|
|
+ s.s = mf->buf.s;
|
|
|
|
+ s.len = mf->buf.len;
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 2:
|
|
|
|
+ if(mf->mbody.s==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ s.s = mf->mbody.s;
|
|
|
|
+ s.len = mf->mbody.len;
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 3:
|
|
|
|
+ if(mf->fline.msgtypeid==MSRP_REQUEST)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ return pv_get_intstrval(msg, param, res, mf->fline.rtypeid,
|
|
|
|
+ &mf->fline.rtype);
|
|
|
|
+ case 4:
|
|
|
|
+ if(mf->hbody.s==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ s.s = mf->hbody.s;
|
|
|
|
+ s.len = mf->hbody.len;
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 5:
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_MESSAGE_ID);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ s.s = hdr->body.s;
|
|
|
|
+ s.len = hdr->body.len;
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 6:
|
|
|
|
+ if(mf->fline.msgtypeid==MSRP_REPLY)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ return pv_get_strintval(msg, param, res, &mf->fline.rtype,
|
|
|
|
+ mf->fline.rtypeid);
|
|
|
|
+ case 7:
|
|
|
|
+ return pv_get_uintval(msg, param, res, mf->buf.len);
|
|
|
|
+ case 8:
|
|
|
|
+ if(msrp_parse_hdr_to_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ s = sar->list[0];
|
|
|
|
+ trim(&s);
|
|
|
|
+ if(msrp_parse_uri(s.s, s.len, &uri)<0 || uri.session.len<=0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ s = uri.session;
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 9:
|
|
|
|
+ if(mf->fline.msgtypeid==MSRP_REQUEST || mf->fline.rtext.s==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ return pv_get_strval(msg, param, res, &mf->fline.rtext);
|
|
|
|
+ case 10:
|
|
|
|
+ return pv_get_uintval(msg, param, res, mf->mbody.len);
|
|
|
|
+ case 11:
|
|
|
|
+ s = mf->fline.transaction;
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 12:
|
|
|
|
+ if(msrp_parse_hdr_to_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ s = sar->list[0];
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 13:
|
|
|
|
+ if(msrp_parse_hdr_from_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ s = sar->list[0];
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 14:
|
|
|
|
+ if(msrp_parse_hdr_to_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ if(sar->size<2)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ s = sar->list[1];
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 15:
|
|
|
|
+ if(msrp_parse_hdr_to_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ s = sar->list[sar->size-1];
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 16:
|
|
|
|
+ if(msrp_parse_hdr_from_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ s = sar->list[sar->size-1];
|
|
|
|
+ trim(&s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 17:
|
|
|
|
+ if(msrp_parse_hdr_from_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ return pv_get_uintval(msg, param, res, sar->size);
|
|
|
|
+ case 18:
|
|
|
|
+ if(msrp_parse_hdr_from_path(mf)<0)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
|
|
|
|
+ if(hdr==NULL)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ sar = (str_array_t*)hdr->parsed.data;
|
|
|
|
+ return pv_get_uintval(msg, param, res, sar->size-1);
|
|
|
|
+ case 19:
|
|
|
|
+ if(pv_get_buffer_size()<100)
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ s.s = pv_get_buffer();
|
|
|
|
+ p = s.s;
|
|
|
|
+ if(mf->tcpinfo->rcv->proto==PROTO_TLS)
|
|
|
|
+ {
|
|
|
|
+ memcpy(p, "msrps://", 8);
|
|
|
|
+ p+=8;
|
|
|
|
+ } else {
|
|
|
|
+ memcpy(p, "msrp://", 7);
|
|
|
|
+ p+=7;
|
|
|
|
+ }
|
|
|
|
+ strcpy(p, ip_addr2a(&mf->tcpinfo->rcv->src_ip));
|
|
|
|
+ strcat(p, ":");
|
|
|
|
+ strcat(p, int2str(mf->tcpinfo->rcv->src_port, NULL));
|
|
|
|
+ s.len = strlen(s.s);
|
|
|
|
+ return pv_get_strval(msg, param, res, &s);
|
|
|
|
+ case 20:
|
|
|
|
+ return pv_get_strval(msg, param, res,
|
|
|
|
+ &mf->tcpinfo->rcv->bind_address->sock_str);
|
|
|
|
+ default:
|
|
|
|
+ return pv_get_null(msg, param, res);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+int pv_set_msrp(sip_msg_t *msg, pv_param_t *param, int op,
|
|
|
|
+ pv_value_t *val)
|
|
|
|
+{
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+enum _tr_msrp_type { TR_MSRP_NONE=0, TR_MSRPURI };
|
|
|
|
+enum _tr_msrpuri_subtype {
|
|
|
|
+ TR_MSRPURI_NONE=0, TR_MSRPURI_USER, TR_MSRPURI_HOST, TR_MSRPURI_PORT,
|
|
|
|
+ TR_MSRPURI_SESSION, TR_MSRPURI_PROTO, TR_MSRPURI_USERINFO,
|
|
|
|
+ TR_MSRPURI_PARAMS, TR_MSRPURI_SCHEME};
|
|
|
|
+
|
|
|
|
+static str _tr_empty = { "", 0 };
|
|
|
|
+static str _tr_msrpuri = {0, 0};
|
|
|
|
+static msrp_uri_t _tr_parsed_msrpuri;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+int tr_msrp_eval_msrpuri(struct sip_msg *msg, tr_param_t *tp, int subtype,
|
|
|
|
+ pv_value_t *val)
|
|
|
|
+{
|
|
|
|
+ if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if(_tr_msrpuri.len==0 || _tr_msrpuri.len!=val->rs.len ||
|
|
|
|
+ strncmp(_tr_msrpuri.s, val->rs.s, val->rs.len)!=0)
|
|
|
|
+ {
|
|
|
|
+ if(val->rs.len>_tr_msrpuri.len)
|
|
|
|
+ {
|
|
|
|
+ if(_tr_msrpuri.s) pkg_free(_tr_msrpuri.s);
|
|
|
|
+ _tr_msrpuri.s = (char*)pkg_malloc((val->rs.len+1)*sizeof(char));
|
|
|
|
+ if(_tr_msrpuri.s==NULL)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("no more private memory\n");
|
|
|
|
+ memset(&_tr_msrpuri, 0, sizeof(str));
|
|
|
|
+ memset(&_tr_parsed_msrpuri, 0, sizeof(msrp_uri_t));
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ _tr_msrpuri.len = val->rs.len;
|
|
|
|
+ memcpy(_tr_msrpuri.s, val->rs.s, val->rs.len);
|
|
|
|
+ _tr_msrpuri.s[_tr_msrpuri.len] = '\0';
|
|
|
|
+ /* reset old values */
|
|
|
|
+ memset(&_tr_parsed_msrpuri, 0, sizeof(msrp_uri_t));
|
|
|
|
+ /* parse uri */
|
|
|
|
+ if(msrp_parse_uri(_tr_msrpuri.s, _tr_msrpuri.len,
|
|
|
|
+ &_tr_parsed_msrpuri)!=0)
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("invalid uri [%.*s]\n", val->rs.len,
|
|
|
|
+ val->rs.s);
|
|
|
|
+ pkg_free(_tr_msrpuri.s);
|
|
|
|
+ memset(&_tr_msrpuri, 0, sizeof(str));
|
|
|
|
+ memset(&_tr_parsed_msrpuri, 0, sizeof(msrp_uri_t));
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ memset(val, 0, sizeof(pv_value_t));
|
|
|
|
+ val->flags = PV_VAL_STR;
|
|
|
|
+
|
|
|
|
+ switch(subtype)
|
|
|
|
+ {
|
|
|
|
+ case TR_MSRPURI_USER:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.user.s)?_tr_parsed_msrpuri.user:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_USERINFO:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.userinfo.s)?_tr_parsed_msrpuri.userinfo:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_HOST:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.host.s)?_tr_parsed_msrpuri.host:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_PORT:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.port.s)?_tr_parsed_msrpuri.port:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_SESSION:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.session.s)?_tr_parsed_msrpuri.session:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_PROTO:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.proto.s)?_tr_parsed_msrpuri.proto:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_PARAMS:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.params.s)?_tr_parsed_msrpuri.params:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ case TR_MSRPURI_SCHEME:
|
|
|
|
+ val->rs = (_tr_parsed_msrpuri.scheme.s)?_tr_parsed_msrpuri.scheme:_tr_empty;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ LM_ERR("unknown subtype %d\n",
|
|
|
|
+ subtype);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+char* tr_parse_msrpuri(str* in, trans_t *t)
|
|
|
|
+{
|
|
|
|
+ str name;
|
|
|
|
+ char *p;
|
|
|
|
+
|
|
|
|
+ if(in==NULL || t==NULL)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ p = in->s;
|
|
|
|
+ name.s = in->s;
|
|
|
|
+ t->type = TR_MSRPURI;
|
|
|
|
+ t->trf = tr_msrp_eval_msrpuri;
|
|
|
|
+
|
|
|
|
+ /* find next token */
|
|
|
|
+ while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
|
|
|
|
+ if(*p=='\0')
|
|
|
|
+ {
|
|
|
|
+ LM_ERR("invalid transformation: %.*s\n",
|
|
|
|
+ in->len, in->s);
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+ name.len = p - name.s;
|
|
|
|
+ trim(&name);
|
|
|
|
+
|
|
|
|
+ if(name.len==4 && strncasecmp(name.s, "user", 4)==0)
|
|
|
|
+ {
|
|
|
|
+ t->subtype = TR_MSRPURI_USER;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==4 && strncasecmp(name.s, "host", 4)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_HOST;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==4 && strncasecmp(name.s, "port", 4)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_PORT;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==7 && strncasecmp(name.s, "session", 7)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_SESSION;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==5 && strncasecmp(name.s, "proto", 5)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_PROTO;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==6 && strncasecmp(name.s, "scheme", 6)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_SCHEME;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==6 && strncasecmp(name.s, "params", 6)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_PARAMS;
|
|
|
|
+ goto done;
|
|
|
|
+ } else if(name.len==8 && strncasecmp(name.s, "userinfo", 8)==0) {
|
|
|
|
+ t->subtype = TR_MSRPURI_USERINFO;
|
|
|
|
+ goto done;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
|
|
|
|
+ name.len, name.s, name.len);
|
|
|
|
+error:
|
|
|
|
+ return NULL;
|
|
|
|
+done:
|
|
|
|
+ t->name = name;
|
|
|
|
+ return p;
|
|
|
|
+
|
|
|
|
+}
|