Esempio n. 1
0
/* introduce a new uac to transaction; returns its branch id (>=0)
   or error (<0); it doesn't send a message yet -- a reply to it
   might interfere with the processes of adding multiple branches
*/
static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
		str* next_hop, unsigned int bflags, str* path, struct proxy_l *proxy)
{
	unsigned short branch;
	struct sip_msg_body *body_clone=NO_BODY_CLONE_MARKER;
	int do_free_proxy;
	int ret;

	branch=t->nr_of_outgoings;
	if (branch==MAX_BRANCHES) {
		LM_ERR("maximum number of branches exceeded\n");
		ret=E_CFG;
		goto error;
	}

	/* check existing buffer -- rewriting should never occur */
	if (t->uac[branch].request.buffer.s) {
		LM_CRIT("buffer rewrite attempt\n");
		ret=ser_error=E_BUG;
		goto error;
	}

	/* set proper RURI to request to reflect the branch */
	request->new_uri=*uri;
	request->parsed_uri_ok=0;
	request->dst_uri=*next_hop;
	request->path_vec=*path;
	request->ruri_bflags=bflags;

	if ( pre_print_uac_request( t, branch, request, &body_clone)!= 0 ) {
		ret = -1;
		goto error01;
	}

	/* check DNS resolution */
	if (proxy){
		do_free_proxy = 0;
	}else {
		proxy=uri2proxy( request->dst_uri.len ?
			&request->dst_uri:&request->new_uri,
			request->force_send_socket ?
				request->force_send_socket->proto : PROTO_NONE );
		if (proxy==0)  {
			ret=E_BAD_ADDRESS;
			goto error01;
		}
		do_free_proxy = 1;
	}

	msg_callback_process(request, REQ_PRE_FORWARD, (void *)proxy);

	if ( !(t->flags&T_NO_DNS_FAILOVER_FLAG) ) {
		t->uac[branch].proxy = shm_clone_proxy( proxy , do_free_proxy );
		if (t->uac[branch].proxy==NULL) {
			ret = E_OUT_OF_MEM;
			goto error02;
		}
	}

	/* use the first address */
	hostent2su( &t->uac[branch].request.dst.to,
		&proxy->host, proxy->addr_idx, proxy->port ? proxy->port:SIP_PORT);
	t->uac[branch].request.dst.proto = proxy->proto;

	/* do print of the uac request */
	if ( update_uac_dst( request, &t->uac[branch] )!=0) {
		ret = ser_error;
		goto error02;
	}

	/* things went well, move ahead */
	t->uac[branch].uri.s=t->uac[branch].request.buffer.s+
		request->first_line.u.request.method.len+1;
	t->uac[branch].uri.len=request->new_uri.len;
	t->uac[branch].br_flags = request->ruri_bflags;
	t->uac[branch].added_rr = count_local_rr( request );
	t->nr_of_outgoings++;

	/* done! */
	ret=branch;

error02:
	if(do_free_proxy) {
		free_proxy( proxy );
		pkg_free( proxy );
	}
error01:
	post_print_uac_request( request, uri, next_hop, body_clone);
	if (ret < 0) {
		/* destroy all the bavps added, the path vector and the destination,
		 * since this branch will never be properly added to
		 * the UAC list, otherwise we'll have memory leaks - razvanc */
		clean_branch(t->uac[branch]);
		memset(&t->uac[branch], 0, sizeof(t->uac[branch]));
		init_branch(&t->uac[branch], branch, t->wait_tl.set, t);
	}
error:
	return ret;
}
Esempio n. 2
0
int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
	struct cell *t_invite, int branch )
{
	int ret;
	char *shbuf;
	unsigned int len;
	str bk_dst_uri;
	str bk_path_vec;

	if (t_cancel->uac[branch].request.buffer.s) {
		LM_CRIT("buffer rewrite attempt\n");
		ret=ser_error=E_BUG;
		goto error;
	}

	cancel_msg->new_uri = t_invite->uac[branch].uri;
	cancel_msg->parsed_uri_ok=0;
	bk_dst_uri = cancel_msg->dst_uri;
	bk_path_vec = cancel_msg->path_vec;

	/* force same path as for request */
	cancel_msg->path_vec = t_invite->uac[branch].path_vec;

	if ( pre_print_uac_request( t_cancel, branch, cancel_msg)!= 0 ) {
		ret = -1;
		goto error01;
	}

	/* force same uri as in INVITE */
	if (cancel_msg->new_uri.s!=t_invite->uac[branch].uri.s) {
		pkg_free(cancel_msg->new_uri.s);
		cancel_msg->new_uri = t_invite->uac[branch].uri;
		/* and just to be sure */
		cancel_msg->parsed_uri_ok = 0;
	}

	/* print */
	shbuf=print_uac_request( cancel_msg, &len,
		t_invite->uac[branch].request.dst.send_sock,
		t_invite->uac[branch].request.dst.proto);
	if (!shbuf) {
		LM_ERR("printing e2e cancel failed\n");
		ret=ser_error=E_OUT_OF_MEM;
		goto error01;
	}

	/* install buffer */
	t_cancel->uac[branch].request.dst=t_invite->uac[branch].request.dst;
	t_cancel->uac[branch].request.buffer.s=shbuf;
	t_cancel->uac[branch].request.buffer.len=len;
	t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer.s+
		cancel_msg->first_line.u.request.method.len+1;
	t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len;
	t_cancel->uac[branch].br_flags = cancel_msg->flags;

	/* success */
	ret=1;

error01:
	post_print_uac_request( cancel_msg, &t_invite->uac[branch].uri,
		&bk_dst_uri);
	cancel_msg->dst_uri = bk_dst_uri;
	cancel_msg->path_vec = bk_path_vec;
error:
	return ret;
}
Esempio n. 3
0
int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, 
	struct cell *t_invite, int branch )
{
	int ret;
	char *shbuf;
	unsigned int len;
	str bk_dst_uri;

	if (t_cancel->uac[branch].request.buffer) {
		LOG(L_CRIT, "ERROR: e2e_cancel_branch: buffer rewrite attempt\n");
		ret=ser_error=E_BUG;
		goto error;
	}

	/* note -- there is a gap in proxy stats -- we don't update 
	   proxy stats with CANCEL (proxy->ok, proxy->tx, etc.) */
	cancel_msg->new_uri = t_invite->uac[branch].uri;
	cancel_msg->parsed_uri_ok=0;
	bk_dst_uri = cancel_msg->dst_uri;

	if ( pre_print_uac_request( t_cancel, branch, cancel_msg)!= 0 ) {
		ret = -1;
		goto error01;
	}

	/* force same uri as in INVITE */
	if (cancel_msg->new_uri.s!=t_invite->uac[branch].uri.s) {
		pkg_free(cancel_msg->new_uri.s);
		cancel_msg->new_uri = t_invite->uac[branch].uri;
		/* and just to be sure */
		cancel_msg->parsed_uri_ok = 0;
	}

	/* print */
	shbuf=print_uac_request( cancel_msg, &len,
		t_invite->uac[branch].request.dst.send_sock,
		t_invite->uac[branch].request.dst.proto);
	if (!shbuf) {
		LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
		ret=ser_error=E_OUT_OF_MEM;
		goto error01;
	}

	/* install buffer */
	t_cancel->uac[branch].request.dst=t_invite->uac[branch].request.dst;
	t_cancel->uac[branch].request.buffer=shbuf;
	t_cancel->uac[branch].request.buffer_len=len;
	t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer+
		cancel_msg->first_line.u.request.method.len+1;
	t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len;
	t_cancel->uac[branch].br_flags = cancel_msg->flags&(~gflags_mask);

	/* success */
	ret=1;

error01:
	post_print_uac_request( cancel_msg, &t_invite->uac[branch].uri,
		&bk_dst_uri);
	cancel_msg->dst_uri = bk_dst_uri;
error:
	return ret;
}
Esempio n. 4
0
/* introduce a new uac to transaction; returns its branch id (>=0)
   or error (<0); it doesn't send a message yet -- a reply to it
   might interfere with the processes of adding multiple branches
*/
static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
							str* next_hop, str* path, struct proxy_l *proxy)
{
	unsigned short branch;
	int do_free_proxy;
	int ret;

	branch=t->nr_of_outgoings;
	if (branch==MAX_BRANCHES) {
		LM_ERR("maximum number of branches exceeded\n");
		ret=E_CFG;
		goto error;
	}

	/* check existing buffer -- rewriting should never occur */
	if (t->uac[branch].request.buffer.s) {
		LM_CRIT("buffer rewrite attempt\n");
		ret=ser_error=E_BUG;
		goto error;
	}

	/* set proper RURI to request to reflect the branch */
	request->new_uri=*uri;
	request->parsed_uri_ok=0;
	request->dst_uri=*next_hop;
	request->path_vec=*path;

	if ( pre_print_uac_request( t, branch, request)!= 0 ) {
		ret = -1;
		goto error01;
	}

	/* check DNS resolution */
	if (proxy){
		do_free_proxy = 0;
	}else {
		proxy=uri2proxy( request->dst_uri.len ?
			&request->dst_uri:&request->new_uri, PROTO_NONE );
		if (proxy==0)  {
			ret=E_BAD_ADDRESS;
			goto error01;
		}
		do_free_proxy = 1;
	}

	msg_callback_process(request, REQ_PRE_FORWARD, (void *)proxy);

	if ( !(t->flags&T_NO_DNS_FAILOVER_FLAG) ) {
		t->uac[branch].proxy = shm_clone_proxy( proxy , do_free_proxy );
		if (t->uac[branch].proxy==NULL) {
			ret = E_OUT_OF_MEM;
			goto error02;
		}
	}

	/* use the first address */
	hostent2su( &t->uac[branch].request.dst.to,
		&proxy->host, proxy->addr_idx, proxy->port ? proxy->port:SIP_PORT);
	t->uac[branch].request.dst.proto = proxy->proto;

	if ( update_uac_dst( request, &t->uac[branch] )!=0) {
		ret = ser_error;
		goto error02;
	}

	/* things went well, move ahead */
	t->uac[branch].uri.s=t->uac[branch].request.buffer.s+
		request->first_line.u.request.method.len+1;
	t->uac[branch].uri.len=request->new_uri.len;
	t->uac[branch].br_flags = getb0flags();
	t->uac[branch].added_rr = count_local_rr( request );
	t->nr_of_outgoings++;

	/* done! */
	ret=branch;

error02:
	if(do_free_proxy) {
		free_proxy( proxy );
		pkg_free( proxy );
	}
error01:
	post_print_uac_request( request, uri, next_hop);
error:
	return ret;
}
Esempio n. 5
0
/* introduce a new uac to transaction; returns its branch id (>=0)
   or error (<0); it doesn't send a message yet -- a reply to it
   might interfere with the processes of adding multiple branches
*/
int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
	struct proxy_l *proxy, int proto )
{
	int ret;
	short temp_proxy;
	union sockaddr_union to;
	unsigned short branch;
	struct socket_info* send_sock;
	char *shbuf;
	unsigned int len;

	branch=t->nr_of_outgoings;
	if (branch==MAX_BRANCHES) {
		LOG(L_ERR, "ERROR:tm:add_uac: maximum number of branches exceeded\n");
		ret=E_CFG;
		goto error;
	}

	/* check existing buffer -- rewriting should never occur */
	if (t->uac[branch].request.buffer) {
		LOG(L_CRIT, "ERROR:tm:add_uac: buffer rewrite attempt\n");
		ret=ser_error=E_BUG;
		goto error;
	}

	/* set proper RURI to request to reflect the branch */
	request->new_uri=*uri;
	request->parsed_uri_ok=0;
	request->dst_uri=*next_hop;

	if ( pre_print_uac_request( t, branch, request)!= 0 ) {
		ret = -1;
		goto error01;
	}

	/* check DNS resolution */
	if (proxy){
		temp_proxy=0;
		proto=get_proto(proto, proxy->proto);
	}else {
		proxy=uri2proxy( request->dst_uri.len ?
			&request->dst_uri:&request->new_uri, proto );
		if (proxy==0)  {
			ret=E_BAD_ADDRESS;
			goto error01;
		}
		proto=proxy->proto; /* uri2proxy will fix it for us */
		temp_proxy=1;
	}

	if (proxy->ok==0) {
		if (proxy->host.h_addr_list[proxy->addr_idx+1])
			proxy->addr_idx++;
		else proxy->addr_idx=0;
		proxy->ok=1;
	}

	hostent2su( &to, &proxy->host, proxy->addr_idx, 
		proxy->port ? proxy->port:SIP_PORT);

	send_sock=get_send_socket( request, &to , proto);
	if (send_sock==0) {
		LOG(L_ERR, "ERROR:tm:add_uac: can't fwd to af %d, proto %d "
			" (no corresponding listening socket)\n",
			to.s.sa_family, proto );
		ret=ser_error=E_NO_SOCKET;
		goto error02;
	}

	/* now message printing starts ... */
	shbuf=print_uac_request( request, &len, send_sock, proto );
	if (!shbuf) {
		ret=ser_error=E_OUT_OF_MEM;
		goto error02;
	}

	/* things went well, move ahead and install new buffer! */
	t->uac[branch].request.dst.to=to;
	t->uac[branch].request.dst.send_sock=send_sock;
	t->uac[branch].request.dst.proto=proto;
	t->uac[branch].request.dst.proto_reserved1=0;
	t->uac[branch].request.buffer=shbuf;
	t->uac[branch].request.buffer_len=len;
	t->uac[branch].uri.s=t->uac[branch].request.buffer+
		request->first_line.u.request.method.len+1;
	t->uac[branch].uri.len=request->new_uri.len;
	t->uac[branch].br_flags = request->flags&(~gflags_mask);
	t->nr_of_outgoings++;

	/* update stats */
	proxy->tx++;
	proxy->tx_bytes+=len;

	/* done! */
	ret=branch;

error02:
	if (temp_proxy) {
		free_proxy( proxy );
		pkg_free( proxy );
	}
error01:
	post_print_uac_request( request, uri, next_hop);
error:
	return ret;
}