Beispiel #1
0
static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
{
	struct sip_msg *shm_msg;
	unsigned int timeout; /* avp timeout gets stored here (in s) */

	shm_msg=new_cell->uas.request;
	new_cell->from.s=shm_msg->from->name.s;
	new_cell->from.len=HF_LEN(shm_msg->from);
	new_cell->to.s=shm_msg->to->name.s;
	new_cell->to.len=HF_LEN(shm_msg->to);
	new_cell->callid.s=shm_msg->callid->name.s;
	new_cell->callid.len=HF_LEN(shm_msg->callid);
	new_cell->cseq_n.s=shm_msg->cseq->name.s;
	new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
		+get_cseq(shm_msg)->number.len
		-shm_msg->cseq->name.s;

	new_cell->method=new_cell->uas.request->first_line.u.request.method;
	if (p_msg->REQ_METHOD==METHOD_INVITE) new_cell->flags |= T_IS_INVITE_FLAG;
	new_cell->on_negative=get_on_negative();
	new_cell->on_reply=get_on_reply();
	new_cell->fr_timeout=(ticks_t)get_msgid_val(user_fr_timeout,
												p_msg->id, int);
	new_cell->fr_inv_timeout=(ticks_t)get_msgid_val(user_fr_inv_timeout,
												p_msg->id, int);
	if (new_cell->fr_timeout==0){
		if (!fr_avp2timer(&timeout)) {
			DBG("init_new_t: FR__TIMER = %d s\n", timeout);
			new_cell->fr_timeout=S_TO_TICKS((ticks_t)timeout);
		}else{
			new_cell->fr_timeout=fr_timeout;
		}
	}
	if (new_cell->fr_inv_timeout==0){
		if (!fr_inv_avp2timer(&timeout)) {
			DBG("init_new_t: FR_INV_TIMER = %d s\n", timeout);
			new_cell->fr_inv_timeout=S_TO_TICKS((ticks_t)timeout);
			new_cell->flags |= T_NOISY_CTIMER_FLAG;
		}else{
			new_cell->fr_inv_timeout=fr_inv_timeout;
		}
	}
	new_cell->on_branch=get_on_branch();
}
static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
{
	struct sip_msg *shm_msg;

	shm_msg=new_cell->uas.request;
	new_cell->from.s=shm_msg->from->name.s;
	new_cell->from.len=HF_LEN(shm_msg->from);
	new_cell->to.s=shm_msg->to->name.s;
	new_cell->to.len=HF_LEN(shm_msg->to);
	new_cell->callid.s=shm_msg->callid->name.s;
	new_cell->callid.len=HF_LEN(shm_msg->callid);
	new_cell->cseq_n.s=shm_msg->cseq->name.s;
	new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
		+get_cseq(shm_msg)->number.len
		-shm_msg->cseq->name.s;

	new_cell->method=new_cell->uas.request->first_line.u.request.method;
	new_cell->is_invite=p_msg->REQ_METHOD==METHOD_INVITE;
	new_cell->on_negative=get_on_negative();
	new_cell->on_reply=get_on_reply();
}
Beispiel #3
0
/* function returns:
 *       1 - forward successfull
 *      -1 - error during forward
 */
int t_forward_nonack( struct cell *t, struct sip_msg* p_msg , 
	struct proxy_l * proxy, int proto)
{
	str          backup_uri;
	int branch_ret, lowest_ret;
	str current_uri;
	branch_bm_t	added_branches;
	int first_branch;
	int i;
	struct cell *t_invite;
	int success_branch;
	int try_new;

	/* make -Wall happy */
	current_uri.s=0;

	set_kr(REQ_FWDED);

	if (p_msg->REQ_METHOD==METHOD_CANCEL) {
		t_invite=t_lookupOriginalT(  p_msg );
		if (t_invite!=T_NULL_CELL) {
			e2e_cancel( p_msg, t, t_invite );
			UNREF(t_invite);
			return 1;
		}
	}

	/* backup current uri ... add_uac changes it */
	backup_uri = p_msg->new_uri;
	/* if no more specific error code is known, use this */
	lowest_ret=E_BUG;
	/* branches added */
	added_branches=0;
	/* branch to begin with */
	first_branch=t->nr_of_outgoings;

	/* on first-time forwarding, use current uri, later only what
	   is in additional branches (which may be continuously refilled
	*/
	if (first_branch==0) {
		try_new=1;
		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg), proxy, proto );
		if (branch_ret>=0) 
			added_branches |= 1<<branch_ret;
		else
			lowest_ret=branch_ret;
	} else try_new=0;

	init_branch_iterator();
	while((current_uri.s=next_branch( &current_uri.len))) {
		try_new++;
		branch_ret=add_uac( t, p_msg, &current_uri, 
				    (p_msg->dst_uri.len) ? (&p_msg->dst_uri) : &current_uri, 
				    proxy, proto);
		/* pick some of the errors in case things go wrong;
		   note that picking lowest error is just as good as
		   any other algorithm which picks any other negative
		   branch result */
		if (branch_ret>=0) 
			added_branches |= 1<<branch_ret;
		else
			lowest_ret=branch_ret;
	}
	/* consume processed branches */
	clear_branches();

	/* restore original URI */
	p_msg->new_uri=backup_uri;

	/* don't forget to clear all branches processed so far */

	/* things went wrong ... no new branch has been fwd-ed at all */
	if (added_branches==0) {
		if (try_new==0) {
			LOG(L_ERR, "ERROR: t_forward_nonack: no branched for fwding\n");
			return -1;
		}
		LOG(L_ERR, "ERROR: t_forward_nonack: failure to add branches\n");
		return lowest_ret;
	}

	/* store script processing value of failure route to transactional
	   context; if currently 0, this forwarding attempt will no longer 
	   result in failure_route on error
	*/
	t->on_negative=get_on_negative();

	/* send them out now */
	success_branch=0;
	for (i=first_branch; i<t->nr_of_outgoings; i++) {
		if (added_branches & (1<<i)) {
			if (SEND_BUFFER( &t->uac[i].request)==-1) {
				LOG(L_ERR, "ERROR: t_forward_nonack: sending request failed\n");
				if (proxy) { proxy->errors++; proxy->ok=0; }
			} else {
				success_branch++;
			}
			start_retr( &t->uac[i].request );
		}
	}
	if (success_branch<=0) {
		ser_error=E_SEND;
		return -1;
	}
	return 1;
}