Ejemplo n.º 1
0
/* Encode branch info from contact struct to str */
static inline int encode_branch_info(str *info, struct contact *con)
{
    char *at, *s;
    int len;

    info->len = con->uri.len + con->dst_uri.len +
		con->path.len + MAX_SOCKET_STR + INT2STR_MAX_LEN + 5;
    info->s = pkg_malloc(info->len);
    if (!info->s) {
		LM_ERR("no memory left for branch info\n");
		return 0;
    }
    at = info->s;
    append_str(at, con->uri.s, con->uri.len);
    append_chr(at, '\n');
    append_str(at, con->dst_uri.s, con->dst_uri.len);
    append_chr(at, '\n');
    append_str(at, con->path.s, con->path.len);
    append_chr(at, '\n');
    if (con->sock) {
		len = MAX_SOCKET_STR;
		if (socket2str(at, &len, con->sock) < 0) {
			LM_ERR("failed to convert socket to str\n");
			return 0;
		}
    } else {
		len = 0;
    }
    at = at + len;
    append_chr(at, '\n');
    s = int2str(con->flags, &len);
    append_str(at, s, len);
    append_chr(at, '\n');
    info->len = at - info->s + 1;

    return 1;
}
Ejemplo n.º 2
0
/*
 * Set userpart of URI
 */
int set_uri_user(struct sip_msg* _m, char* _uri, char* _value)
{
    pv_spec_t *uri_pv, *value_pv;
    pv_value_t uri_val, value_val, res_val;
    str uri, value;
    char *at, *colon, *c;
    char new_uri[MAX_URI_SIZE + 1];

    uri_pv = (pv_spec_t *)_uri;
    if (uri_pv && (pv_get_spec_value(_m, uri_pv, &uri_val) == 0)) {
	if (uri_val.flags & PV_VAL_STR) {
	    if (uri_val.rs.len == 0 || uri_val.rs.s == NULL) {
		LM_ERR("missing uri value\n");
		return -1;
	    }
	} else {
	    LM_ERR("uri value is not string\n");
	    return -1;
	}
    } else {
	LM_ERR("failed to get uri value\n");
	return -1;
    }
    uri = uri_val.rs;

    value_pv = (pv_spec_t *)_value;
    if (value_pv && (pv_get_spec_value(_m, value_pv, &value_val) == 0)) {
	if (value_val.flags & PV_VAL_STR) {
	    if (value_val.rs.s == NULL) {
		LM_ERR("missing uriuser value\n");
		return -1;
	    }
	} else {
	    LM_ERR("uriuser value is not string\n");
	    return -1;
	}
    } else {
	LM_ERR("failed to get uriuser value\n");
	return -1;
    }
    value = value_val.rs;

    colon = strchr(uri.s, ':');
    if (colon == NULL) {
	LM_ERR("uri does not contain ':' character\n");
	return -1;
    }
    at = strchr(uri.s, '@');
    c = &(new_uri[0]);
    if (at == NULL) {
	if (value.len == 0) return 1;
	if (uri.len + value.len > MAX_URI_SIZE) {
	    LM_ERR("resulting uri would be too large\n");
	    return -1;
	}
	append_str(c, uri.s, colon - uri.s + 1);
	append_str(c, value.s, value.len);
	append_chr(c, '@');
	append_str(c, colon + 1, uri.len - (colon - uri.s + 1));
	res_val.rs.len = uri.len + value.len + 1;
    } else {
	if (value.len == 0) {
	    append_str(c, uri.s, colon - uri.s + 1);
	    append_str(c, at + 1, uri.len - (at - uri.s + 1));
	    res_val.rs.len = uri.len - (at - colon);
	} else {
	    if (uri.len + value.len - (at - colon - 1) > MAX_URI_SIZE) {
		LM_ERR("resulting uri would be too large\n");
		return -1;
	    }
	    append_str(c, uri.s, colon - uri.s + 1);
	    append_str(c, value.s, value.len);
	    append_str(c, at, uri.len - (at - uri.s));
	    res_val.rs.len = uri.len + value.len - (at - colon - 1);
	}
    }

    res_val.rs.s = &(new_uri[0]);
    LM_DBG("resulting uri: %.*s\n", res_val.rs.len, res_val.rs.s);
    res_val.flags = PV_VAL_STR;
    uri_pv->setf(_m, &uri_pv->pvp, (int)EQ_T, &res_val);

    return 1;
}
Ejemplo n.º 3
0
/*
 * Converts URI, if it is tel URI, to SIP URI.  Returns 1, if
 * conversion succeeded or if no conversion was needed, i.e., URI was not
 * tel URI.  Returns -1, if conversion failed.  Takes SIP URI hostpart from
 * second parameter and (if needed) writes the result to third paramater.
 */
int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
{
    str uri, hostpart, tel_uri, sip_uri;
    char *at;
    int i, j, in_tel_parameters = 0;
    pv_spec_t *res;
    pv_value_t res_val;

    /* get parameters */
    if (get_str_fparam(&uri, _msg, (fparam_t*)_uri) < 0) {
	LM_ERR("failed to get uri value\n");
    }
    if (get_str_fparam(&hostpart, _msg, (fparam_t*)_hostpart) < 0) {
	LM_ERR("failed to get hostpart value\n");
    }
    res = (pv_spec_t *)_res;

    /* check if anything needs to be done */
    if (uri.len < 4) return 1;
    if (strncasecmp(uri.s, "tel:", 4) != 0) return 1;
    
    /* reserve memory for clean tel uri */
    tel_uri.s = pkg_malloc(uri.len+1);
    if (tel_uri.s == 0) {
	LM_ERR("no more pkg memory\n");
	return -1;
    }
	
    /* Remove visual separators before converting to SIP URI. Don't remove 
       visual separators in TEL URI parameters (after the first ";") */
    for (i=0, j=0; i < uri.len; i++) {
	if (in_tel_parameters == 0) {
	    if (uri.s[i] == ';')
		in_tel_parameters = 1;
	}
	if (in_tel_parameters == 0) {
	    if ((uri.s[i] != '-') && (uri.s[i] != '.') && 
		(uri.s[i] != '(') && (uri.s[i] != ')'))
		tel_uri.s[j++] = tolower(uri.s[i]);
	} else {
	    tel_uri.s[j++] = tolower(uri.s[i]);
	}
    }
    tel_uri.s[j] = '\0';
    tel_uri.len = strlen(tel_uri.s);

    /* reserve memory for resulting sip uri */
    sip_uri.len = 4 + tel_uri.len - 4 + 1 + hostpart.len + 1 + 10;
    sip_uri.s = pkg_malloc(sip_uri.len);
    if (sip_uri.s == 0) {
	LM_ERR("no more pkg memory\n");
	pkg_free(tel_uri.s);
	return -1;
    }

    /* create resulting sip uri */
    at = sip_uri.s;
    append_str(at, "sip:", 4);
    append_str(at, tel_uri.s + 4, tel_uri.len - 4);
    append_chr(at, '@');
    append_str(at, hostpart.s, hostpart.len);
    append_chr(at, ';');
    append_str(at, "user=phone", 10);

    /* tel_uri is not needed anymore */
    pkg_free(tel_uri.s);

    /* set result pv value and write sip uri to result pv */
    res_val.rs = sip_uri;
    res_val.flags = PV_VAL_STR;
    if (res->setf(_msg, &res->pvp, (int)EQ_T, &res_val) != 0) {
	LM_ERR("failed to set result pvar\n");
	pkg_free(sip_uri.s);
	return -1;
    }

    /* free allocated pkg memory and return */
    pkg_free(sip_uri.s);
    return 1;
}
Ejemplo n.º 4
0
static int assemble_msg(struct sip_msg* msg, struct tw_info *twi)
{
	static char     id_buf[IDBUF_LEN];
	static char     route_buffer[ROUTE_BUFFER_MAX];
	static char     append_buf[APPEND_BUFFER_MAX];
	static char     cmd_buf[CMD_BUFFER_MAX];
	static str      empty_param = {".",1};
	unsigned int      hash_index, label;
	contact_body_t*   cb=0;
	contact_t*        c=0;
	name_addr_t       na;
	rr_t*             record_route;
	struct hdr_field* p_hdr;
	param_hooks_t     hooks;
	int               l;
	char*             s, fproxy_lr;
	str               route, next_hop, append, tmp_s, body, str_uri;

	if(msg->first_line.type != SIP_REQUEST){
		LM_ERR("called for something else then a SIP request\n");
		goto error;
	}

	/* parse all -- we will need every header field for a UAS */
	if ( parse_headers(msg, HDR_EOH_F, 0)==-1) {
		LM_ERR("parse_headers failed\n");
		goto error;
	}

	/* find index and hash; (the transaction can be safely used due 
	 * to refcounting till script completes) */
	if( t_get_trans_ident(msg,&hash_index,&label) == -1 ) {
		LM_ERR("t_get_trans_ident failed\n");
		goto error;
	}

	 /* parse from header */
	if (msg->from->parsed==0 && parse_from_header(msg)<0 ) {
		LM_ERR("failed to parse <From:> header\n");
		goto error;
	}

	/* parse the RURI (doesn't make any malloc) */
	msg->parsed_uri_ok = 0; /* force parsing */
	if (parse_sip_msg_uri(msg)<0) {
		LM_ERR("uri has not been parsed\n");
		goto error;
	}

	/* parse contact header */
	str_uri.s = 0;
	str_uri.len = 0;
	if(msg->contact) {
		if (msg->contact->parsed==0 && parse_contact(msg->contact)<0) {
			LM_ERR("failed to parse <Contact:> header\n");
			goto error;
		}
		cb = (contact_body_t*)msg->contact->parsed;
		if(cb && (c=cb->contacts)) {
			str_uri = c->uri;
			if (find_not_quoted(&str_uri,'<')) {
				parse_nameaddr(&str_uri,&na);
				str_uri = na.uri;
			}
		}
	}

	/* str_uri is taken from caller's contact or from header
	 * for backwards compatibility with pre-3261 (from is already parsed)*/
	if(!str_uri.len || !str_uri.s)
		str_uri = get_from(msg)->uri;

	/* parse Record-Route headers */
	route.s = s = route_buffer; route.len = 0;
	fproxy_lr = 0;
	next_hop = empty_param;

	p_hdr = msg->record_route;
	if(p_hdr) {
		if (p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ) {
			LM_ERR("failed to parse 'Record-Route:' header\n");
			goto error;
		}
		record_route = (rr_t*)p_hdr->parsed;
	} else {
		record_route = 0;
	}

	if( record_route ) {
		if ( (tmp_s.s=find_not_quoted(&record_route->nameaddr.uri,';'))!=0 &&
		tmp_s.s+1!=record_route->nameaddr.uri.s+
		record_route->nameaddr.uri.len) {
			/* Parse all parameters */
			tmp_s.len = record_route->nameaddr.uri.len - (tmp_s.s-
				record_route->nameaddr.uri.s);
			if (parse_params( &tmp_s, CLASS_URI, &hooks, 
			&record_route->params) < 0) {
				LM_ERR("failed to parse record route uri params\n");
				goto error;
			}
			fproxy_lr = (hooks.uri.lr != 0);
			LM_DBG("record_route->nameaddr.uri: %.*s\n",
				record_route->nameaddr.uri.len,record_route->nameaddr.uri.s);
			if(fproxy_lr){
				LM_DBG("first proxy has loose routing\n");
				copy_route(s,route.len,record_route->nameaddr.uri.s,
					record_route->nameaddr.uri.len);
			}
		}
		for(p_hdr = p_hdr->next;p_hdr;p_hdr = p_hdr->next) {
			/* filter out non-RR hdr and empty hdrs */
			if( (p_hdr->type!=HDR_RECORDROUTE_T) || p_hdr->body.len==0)
				continue;

			if(p_hdr->parsed==0 && parse_rr(p_hdr)!=0 ){
				LM_ERR("failed to parse <Record-route:> header\n");
				goto error;
			}
			for(record_route=p_hdr->parsed; record_route;
				record_route=record_route->next){
				LM_DBG("record_route->nameaddr.uri: <%.*s>\n",
					record_route->nameaddr.uri.len,
					record_route->nameaddr.uri.s);
				copy_route(s,route.len,record_route->nameaddr.uri.s,
					record_route->nameaddr.uri.len);
			}
		}

		if(!fproxy_lr){
			copy_route(s,route.len,str_uri.s,str_uri.len);
			str_uri = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
		} else {
			next_hop = ((rr_t*)msg->record_route->parsed)->nameaddr.uri;
		}
	}

	LM_DBG("calculated route: %.*s\n",route.len,route.len ? route.s : "");
	LM_DBG("next r-uri: %.*s\n",str_uri.len,str_uri.len ? str_uri.s : "");

	if ( REQ_LINE(msg).method_value==METHOD_INVITE || 
	(twi->append && twi->append->add_body) ) {
		/* get body */
		if( (body.s = get_body(msg)) == 0 ){
			LM_ERR("get_body failed\n");
			goto error;
		}
		body.len = msg->len - (body.s - msg->buf);
	} else {
		body = empty_param;
	}

	/* flags & additional headers */
	append.s = s = append_buf;
	if (sizeof(flag_t)*2+12+1 >= APPEND_BUFFER_MAX) {
		LM_ERR("buffer overflow while copying flags\n");
		goto error;
	}
	append_str(s,"P-MsgFlags: ",12);
	l = APPEND_BUFFER_MAX - (12+1); /* include trailing `\n'*/

	if (int2reverse_hex(&s, &l, (int)msg->msg_flags) == -1) {
		LM_ERR("buffer overflow while copying optional header\n");
		goto error;
	}
	append_chr(s,'\n');

	if ( twi->append && ((s=append2buf( s, APPEND_BUFFER_MAX-(s-append.s), msg,
	twi->append->elems))==0) )
		goto error;

	/* body separator */
	append_chr(s,'.');
	append.len = s-append.s;

	eol_line(1).s = s = cmd_buf;
	if(twi->action.len+12 >= CMD_BUFFER_MAX){
		LM_ERR("buffer overflow while copying command name\n");
		goto error;
	}
	append_str(s,"sip_request.",12);
	append_str(s,twi->action.s,twi->action.len);
	eol_line(1).len = s-eol_line(1).s;

	eol_line(2)=REQ_LINE(msg).method;     /* method type */
	eol_line(3)=msg->parsed_uri.user;     /* user from r-uri */
	eol_line(4)=msg->parsed_uri.host;     /* domain */

	eol_line(5)=msg->rcv.bind_address->address_str; /* dst ip */

	eol_line(6)=msg->rcv.dst_port==SIP_PORT ?
			empty_param : msg->rcv.bind_address->port_no_str; /* port */

	/* r_uri ('Contact:' for next requests) */
	eol_line(7)=*GET_RURI(msg);

	/* r_uri for subsequent requests */
	eol_line(8)=str_uri.len?str_uri:empty_param;

	eol_line(9)=get_from(msg)->body;		/* from */
	eol_line(10)=msg->to->body;			/* to */
	eol_line(11)=msg->callid->body;		/* callid */
	eol_line(12)=get_from(msg)->tag_value;	/* from tag */
	eol_line(13)=get_to(msg)->tag_value;	/* to tag */
	eol_line(14)=get_cseq(msg)->number;	/* cseq number */

	eol_line(15).s=id_buf;       /* hash:label */
	s = int2str(hash_index, &l);
	if (l+1>=IDBUF_LEN) {
		LM_ERR("too big hash\n");
		goto error;
	}
	memcpy(id_buf, s, l);
	id_buf[l]=':';
	eol_line(15).len=l+1;
	s = int2str(label, &l);
	if (l+1+eol_line(15).len>=IDBUF_LEN) {
		LM_ERR("too big label\n");
		goto error;
	}
	memcpy(id_buf+eol_line(15).len, s, l);
	eol_line(15).len+=l;

	eol_line(16) = route.len ? route : empty_param;
	eol_line(17) = next_hop;
	eol_line(18) = append;
	eol_line(19) = body;

	/* success */
	return 1;
error:
	/* 0 would lead to immediate script exit -- -1 returns
	 * with 'false' to script processing */
	return -1;
}