Example #1
0
int msrp_parse_hdr_to_path(msrp_frame_t *mf)
{
	msrp_hdr_t *hdr;

	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
	if(hdr==NULL)
		return -1;
	if(hdr->parsed.flags&MSRP_DATA_SET)
		return 0;
	return msrp_parse_hdr_uri_list(hdr);
}
Example #2
0
int msrp_frame_get_expires(msrp_frame_t *mf, int *expires)
{
	msrp_hdr_t *hdr;

	if(msrp_parse_hdr_expires(mf)<0)
		return -1;
	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_AUTH);
	if(hdr==NULL)
		return -1;
	*expires = (int)(long)hdr->parsed.data;
	return 0;
}
Example #3
0
int msrp_frame_get_first_from_path(msrp_frame_t *mf, str *sres)
{
	str s = {0};
	msrp_hdr_t *hdr;
	str_array_t *sar;

	if(msrp_parse_hdr_from_path(mf)<0)
		return -1;
	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
	if(hdr==NULL)
		return -1;
	sar = (str_array_t*)hdr->parsed.data;
	s = sar->list[sar->size-1];
	trim(&s);
	*sres = s;
	return 0;
}
Example #4
0
int msrp_frame_get_sessionid(msrp_frame_t *mf, str *sres)
{
	str s = {0};
	msrp_hdr_t *hdr;
	str_array_t *sar;
	msrp_uri_t uri;

	if(msrp_parse_hdr_to_path(mf)<0)
		return -1;
	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
	if(hdr==NULL)
		return -1;
	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 -1;
	s = uri.session;
	trim(&s);
	*sres = s;

	return 0;
}
Example #5
0
int msrp_parse_hdr_expires(msrp_frame_t *mf)
{
	msrp_hdr_t *hdr;
	str hbody;
	int expires;

	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_EXPIRES);
	if(hdr==NULL)
		return -1;
	if(hdr->parsed.flags&MSRP_DATA_SET)
		return 0;
	hbody = hdr->body;
	trim(&hbody);
	if(str2sint(&hbody, &expires)<0) {
		LM_ERR("invalid expires value\n");
		return -1;
	}
	hdr->parsed.flags |= MSRP_DATA_SET;
	hdr->parsed.free_fn = NULL;
	hdr->parsed.data = (void*)(long)expires;

	return 0;
}
Example #6
0
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,
					MSRP_RPL_CODE(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_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;
			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);
		case 21:
			if(mf->tcpinfo->con==NULL)
				return pv_get_null(msg, param, res);
			return pv_get_sintval(msg, param, res, mf->tcpinfo->con->id);
		default:
			return pv_get_null(msg, param, res);
	}

	return 0;
}
Example #7
0
int msrp_relay(msrp_frame_t *mf)
{
	struct dest_info *dst;
	struct tcp_connection *con = NULL;
	char reqbuf[MSRP_MAX_FRAME_SIZE];
	msrp_hdr_t *tpath;
	msrp_hdr_t *fpath;
	msrp_env_t *env;
	str_array_t *sar;
	char *p;
	char *l;
	int port;

	if(mf->buf.len>=MSRP_MAX_FRAME_SIZE-1)
		return -1;

	tpath = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
	if(tpath==NULL)
	{
		LM_ERR("To-Path header not found\n");
		return -1;
	}
	fpath = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
	if(fpath==NULL)
	{
		LM_ERR("From-Path header not found\n");
		return -1;
	}

	l = q_memchr(tpath->body.s, ' ', tpath->body.len);
	if(l==NULL)
	{
		LM_DBG("To-Path has only one URI -- nowehere to forward\n");
		return -1;
	}

	p = reqbuf;

	memcpy(p, mf->buf.s, tpath->body.s - mf->buf.s);
	p += tpath->body.s - mf->buf.s;

	memcpy(p, l + 1, fpath->body.s - l - 1);
	p += fpath->body.s - l - 1;

	memcpy(p, tpath->body.s, l + 1 - tpath->body.s);
	p += l + 1 - tpath->body.s;

	memcpy(p, fpath->name.s + 11, mf->buf.s + mf->buf.len - fpath->name.s - 11);
	p += mf->buf.s + mf->buf.len - fpath->name.s - 11;

	env = msrp_get_env();
	if(env->envflags&MSRP_ENV_DSTINFO)
	{
		dst = &env->dstinfo;
		goto done;
	}
	if(msrp_parse_hdr_to_path(mf)<0)
	{
		LM_ERR("error parsing To-Path header\n");
		return -1;
	}
	sar = (str_array_t*)tpath->parsed.data;
	if(sar==NULL || sar->size<2)
	{
		LM_DBG("To-Path has no next hop URI -- nowehere to forward\n");
		return -1;
	}
	if(msrp_env_set_dstinfo(mf, &sar->list[1], NULL, 0)<0)
	{
		LM_ERR("unable to set destination address\n");
		return -1;
	}
	dst = &env->dstinfo;
done:
	if (dst->send_flags.f & SND_F_FORCE_CON_REUSE)
	{
		port = su_getport(&dst->to);
		if (likely(port))
		{
			ticks_t con_lifetime;
			struct ip_addr ip;

			con_lifetime = cfg_get(tcp, tcp_cfg, con_lifetime);
			su2ip_addr(&ip, &dst->to);
			con = tcpconn_get(dst->id, &ip, port, NULL, con_lifetime);
		}
		else if (likely(dst->id))
		{
			con = tcpconn_get(dst->id, 0, 0, 0, 0);
		}

		if (con == NULL)
		{
			LM_WARN("TCP/TLS connection not found\n");
			return -1;
		}
	
		if (unlikely((con->rcv.proto == PROTO_WS || con->rcv.proto == PROTO_WSS)
				&& sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
			ws_event_info_t wsev;

			memset(&wsev, 0, sizeof(ws_event_info_t));
			wsev.type = SREV_TCP_WS_FRAME_OUT;
			wsev.buf = reqbuf;
			wsev.len = p - reqbuf;
			wsev.id = con->id;
			return sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
		}
		else if (tcp_send(dst, 0, reqbuf, p - reqbuf) < 0) {
			LM_ERR("forwarding frame failed\n");
			return -1;
		}
	}
	else if (tcp_send(dst, 0, reqbuf, p - reqbuf) < 0) {
			LM_ERR("forwarding frame failed\n");
			return -1;
	}

	return 0;
}
Example #8
0
int msrp_reply(msrp_frame_t *mf, str *code, str *text, str *xhdrs)
{
	char rplbuf[MSRP_MAX_FRAME_SIZE];
	msrp_hdr_t *hdr;
	msrp_env_t *env;
	char *p;
	char *l;

	/* no reply for a reply */
	if(mf->fline.msgtypeid==MSRP_REPLY)
		return 0;

	if(mf->fline.msgtypeid==MSRP_REQ_REPORT)
	{
		/* it does not take replies */
		return 0;
	}

	p = rplbuf;
	memcpy(p, mf->fline.protocol.s, mf->fline.protocol.len);
	p += mf->fline.protocol.len;
	*p = ' '; p++;
	memcpy(p, mf->fline.transaction.s, mf->fline.transaction.len);
	p += mf->fline.transaction.len;
	*p = ' '; p++;
	memcpy(p, code->s, code->len);
	p += code->len;
	*p = ' '; p++;
	memcpy(p, text->s, text->len);
	p += text->len;
	memcpy(p, "\r\n", 2);
	p += 2;
	memcpy(p, "To-Path: ", 9);
	p += 9;
	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_FROM_PATH);
	if(hdr==NULL)
	{
		LM_ERR("From-Path header not found\n");
		return -1;
	}
	if(mf->fline.msgtypeid==MSRP_REQ_SEND)
	{
		l = q_memchr(hdr->body.s, ' ', hdr->body.len);
		if(l==NULL) {
			memcpy(p, hdr->body.s, hdr->body.len + 2);
			p += hdr->body.len + 2;
		} else {
			memcpy(p, hdr->body.s, l - hdr->body.s);
			p += l - hdr->body.s;
			memcpy(p, "\r\n", 2);
			p += 2;
		}
	} else {
		memcpy(p, hdr->body.s, hdr->body.len + 2);
		p += hdr->body.len + 2;
	}
	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_TO_PATH);
	if(hdr==NULL)
	{
		LM_ERR("To-Path header not found\n");
		return -1;
	}
	memcpy(p, "From-Path: ", 11);
	p += 11;
	l = q_memchr(hdr->body.s, ' ', hdr->body.len);
	if(l==NULL) {
		memcpy(p, hdr->body.s, hdr->body.len + 2);
		p += hdr->body.len + 2;
	} else {
		memcpy(p, hdr->body.s, l - hdr->body.s);
		p += l - hdr->body.s;
		memcpy(p, "\r\n", 2);
		p += 2;
	}
	hdr = msrp_get_hdr_by_id(mf, MSRP_HDR_MESSAGE_ID);
	if(hdr!=NULL)
	{
		memcpy(p, hdr->buf.s, hdr->buf.len);
		p += hdr->buf.len;
	}

	if(xhdrs!=NULL && xhdrs->s!=NULL)
	{
		memcpy(p, xhdrs->s, xhdrs->len);
		p += xhdrs->len;
	}

	memcpy(p, mf->endline.s, mf->endline.len);
	p += mf->endline.len;
	*(p-3) = '$';

	env = msrp_get_env();

	if (unlikely((env->srcinfo.proto == PROTO_WS
			|| env->srcinfo.proto == PROTO_WSS)
			&& sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) {
		struct tcp_connection *con = tcpconn_get(env->srcinfo.id, 0, 0,
								0, 0);
		ws_event_info_t wsev;

		if (con == NULL)
		{
			LM_WARN("TCP/TLS connection for WebSocket could not be"
				"found\n");
			return -1;
		}

		memset(&wsev, 0, sizeof(ws_event_info_t));
		wsev.type = SREV_TCP_WS_FRAME_OUT;
		wsev.buf = rplbuf;
		wsev.len = p - rplbuf;
		wsev.id = con->id;
		return sr_event_exec(SREV_TCP_WS_FRAME_OUT, (void *) &wsev);
	}
	else 
	if (tcp_send(&env->srcinfo, 0, rplbuf, p - rplbuf) < 0) {
		LM_ERR("sending reply failed\n");
		return -1;
	}

	return 0;
}