Beispiel #1
0
/*only the content*/
void free_sip_msg(struct sip_msg* msg)
{
	if (msg->msg_cb) { msg_callback_process(msg, MSG_DESTROY, NULL); }
	if (msg->new_uri.s) { pkg_free(msg->new_uri.s); msg->new_uri.len=0; }
	if (msg->set_global_address.s) {
		pkg_free(msg->set_global_address.s);
		msg->set_global_address.s = NULL;
	}
	if (msg->set_global_port.s) {
		pkg_free(msg->set_global_port.s);
		msg->set_global_port.s = NULL;
	}
	if (msg->dst_uri.s) { pkg_free(msg->dst_uri.s); msg->dst_uri.len=0; }
	if (msg->path_vec.s) { pkg_free(msg->path_vec.s); msg->path_vec.len=0; }
	if (msg->headers)     free_hdr_field_lst(msg->headers);
	if (msg->sdp)         free_sdp(&(msg->sdp));
	if (msg->add_rm)      free_lump_list(msg->add_rm);
	if (msg->body_lumps)  free_lump_list(msg->body_lumps);
	if (msg->reply_lump)   free_reply_lump(msg->reply_lump);
	if (msg->multi )  { free_multi_body(msg->multi);msg->multi = 0;}
	/* don't free anymore -- now a pointer to a static buffer */
#	ifdef DYN_BUF
	pkg_free(msg->buf);
#	endif
}
Beispiel #2
0
inline static void free_faked_req(struct sip_msg *faked_req, struct cell *t)
{
	if (faked_req->new_uri.s) {
		pkg_free(faked_req->new_uri.s);
		faked_req->new_uri.s = 0;
	}
	if (faked_req->dst_uri.s) {
		pkg_free(faked_req->dst_uri.s);
		faked_req->dst_uri.s = 0;
	}
	if (faked_req->path_vec.s) {
		pkg_free(faked_req->path_vec.s);
		faked_req->path_vec.s = 0;
	}

	/* SDP in not cloned into SHM, so if we have one, it means the SDP
	 * was parsed in the fake environment, so we have to free it */
	if (faked_req->sdp)
		free_sdp(&(faked_req->sdp));

	if (faked_req->multi) {
		free_multi_body(faked_req->multi);
		faked_req->multi = 0;
	}

	if (faked_req->msg_cb) {
		msg_callback_process(faked_req, MSG_DESTROY, NULL);
	}

	/* free all types of lump that were added in failure handlers */
	del_notflaged_lumps( &(faked_req->add_rm), LUMPFLAG_SHMEM );
	del_notflaged_lumps( &(faked_req->body_lumps), LUMPFLAG_SHMEM );
	del_nonshm_lump_rpl( &(faked_req->reply_lump) );

	clean_msg_clone( faked_req, t->uas.request, t->uas.end_request);
}
Beispiel #3
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;
}
Beispiel #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;
}
int forward_request( struct sip_msg* msg, struct proxy_l * p)
{
	union sockaddr_union to;
	unsigned int len;
	char* buf;
	struct socket_info* send_sock;
	struct socket_info* last_sock;
	str *branch;

	buf=0;

	/* calculate branch for outbound request - if the branch buffer is already
	 * set (maybe by an upper level as TM), used it; otherwise computes 
	 * the branch for stateless fwd. . According to the latest discussions
	 * on the topic, you should reuse the latest statefull branch
	 * --bogdan */
	if ( msg->add_to_branch_len==0 ) {
		branch = get_sl_branch(msg);
		if (branch==0) {
			LM_ERR("unable to compute branch\n");
			goto error;
		}
		msg->add_to_branch_len = branch->len;
		memcpy( msg->add_to_branch_s, branch->s, branch->len);
	}

	msg_callback_process(msg, REQ_PRE_FORWARD, (void *)p);

	hostent2su( &to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
	last_sock = 0;

	if (getb0flags() & tcp_no_new_conn_bflag)
		tcp_no_new_conn = 1;

	do {
		send_sock=get_send_socket( msg, &to, p->proto);
		if (send_sock==0){
			LM_ERR("cannot forward to af %d, proto %d no corresponding"
				"listening socket\n", to.s.sa_family, p->proto);
			ser_error=E_NO_SOCKET;
			continue;
		}

		if ( last_sock!=send_sock ) {

			if (buf)
				pkg_free(buf);

			buf = build_req_buf_from_sip_req(msg, &len, send_sock, p->proto, 0);
			if (!buf){
				LM_ERR("building req buf failed\n");
				tcp_no_new_conn = 0;
				goto error;
			}

			last_sock = send_sock;
		}

		if (check_blacklists( p->proto, &to, buf, len)) {
			LM_DBG("blocked by blacklists\n");
			ser_error=E_IP_BLOCKED;
			continue;
		}

		/* send it! */
		LM_DBG("sending:\n%.*s.\n", (int)len, buf);
		LM_DBG("orig. len=%d, new_len=%d, proto=%d\n",
			msg->len, len, p->proto );

		if (msg_send(send_sock, p->proto, &to, 0, buf, len)<0){
			ser_error=E_SEND;
			continue;
		}

		run_fwd_callbacks( msg, buf, len, send_sock, p->proto, &to);

		ser_error = 0;
		break;

	}while( get_next_su( p, &to, (ser_error==E_IP_BLOCKED)?0:1)==0 );

	tcp_no_new_conn = 0;

	if (ser_error) {
		update_stat( drp_reqs, 1);
		goto error;
	}

	/* sent requests stats */
	update_stat( fwd_reqs, 1);

	pkg_free(buf);
	/* received_buf & line_buf will be freed in receive_msg by free_lump_list*/
	return 0;

error:
	if (buf) pkg_free(buf);
	return -1;
}