Beispiel #1
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;

    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.)
    */

    /* print */
    shbuf=print_uac_request( t_cancel, cancel_msg, branch,
                             &t_invite->uac[branch].uri, &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 error;
    }

    /* 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;


    /* success */
    ret=1;


error:
    return ret;
}
Beispiel #2
0
static inline int update_uac_dst( struct sip_msg *request,
													struct ua_client *uac )
{
	struct socket_info* send_sock;
	char *shbuf;
	unsigned int len;

	send_sock = get_send_socket( request, &uac->request.dst.to ,
			uac->request.dst.proto );
	if (send_sock==0) {
		LM_ERR("failed to fwd to af %d, proto %d "
			" (no corresponding listening socket)\n",
			uac->request.dst.to.s.sa_family, uac->request.dst.proto );
		ser_error=E_NO_SOCKET;
		return -1;
	}

	if (send_sock!=uac->request.dst.send_sock) {
		/* rebuild */
		shbuf = print_uac_request( request, &len, send_sock,
			uac->request.dst.proto);
		if (!shbuf) {
			ser_error=E_OUT_OF_MEM;
			return -1;
		}

		if (uac->request.buffer.s)
			shm_free(uac->request.buffer.s);

		/* things went well, move ahead and install new buffer! */
		uac->request.dst.send_sock = send_sock;
		uac->request.dst.proto_reserved1 = 0;
		uac->request.buffer.s = shbuf;
		uac->request.buffer.len = len;
	}

	return 0;
}
Beispiel #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;
	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;
}
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
*/
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: 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: add_uac: buffer rewrite attempt\n");
        ret=ser_error=E_BUG;
        goto error;
    }

    /* check DNS resolution */
    if (proxy) {
        temp_proxy=0;
        proto=get_proto(proto, proxy->proto);
    } else {
        proxy=uri2proxy( next_hop ? next_hop : uri, proto );
        if (proxy==0)  {
            ret=E_BAD_ADDRESS;
            goto error;
        }
        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: 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 error01;
    }

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

    /* 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=uri->len;
    t->nr_of_outgoings++;

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

    /* done! */
    ret=branch;

error01:
    if (temp_proxy) {
        free_proxy( proxy );
        pkg_free( proxy );
    }
error:
    return ret;
}
Beispiel #5
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;
}