Пример #1
0
/*if msg is set -> it will fake the env. vars conforming with the msg; if NULL
 * the env. will be restore to original */
static inline void faked_env( struct cell *t,struct sip_msg *msg)
{
	static struct cell *backup_t;
	static struct usr_avp **backup_list;
	static struct socket_info* backup_si;
	static int backup_route_type;

	if (msg) {
		swap_route_type( backup_route_type, FAILURE_ROUTE);
		/* tm actions look in beginning whether transaction is
		 * set -- whether we are called from a reply-processing 
		 * or a timer process, we need to set current transaction;
		 * otherwise the actions would attempt to look the transaction
		 * up (unnecessary overhead, refcounting)
		 */
		/* backup */
		backup_t = get_t();
		/* fake transaction */
		set_t(t);
		/* make available the avp list from transaction */
		backup_list = set_avp_list( &t->user_avps );
		/* set default send address to the saved value */
		backup_si = bind_address;
		bind_address = t->uac[0].request.dst.send_sock;
	} else {
		/* restore original environment */
		set_t(backup_t);
		set_route_type( backup_route_type );
		/* restore original avp list */
		set_avp_list( backup_list );
		bind_address = backup_si;
	}
}
Пример #2
0
int t_lookup_ident(struct cell ** trans, unsigned int hash_index, unsigned int label)
{
    struct cell* p_cell;

    if(hash_index >= TABLE_ENTRIES){
		LOG(L_ERR,"ERROR: t_lookup_ident: invalid hash_index=%u\n",hash_index);
		return -1;
    }

    LOCK_HASH(hash_index);

    /* all the transactions from the entry are compared */
    for ( p_cell = get_tm_table()->entrys[hash_index].first_cell;
	  p_cell; p_cell = p_cell->next_cell ) 
    {
		if(p_cell->label == label){
			REF_UNSAFE(p_cell);
    			UNLOCK_HASH(hash_index);
			set_t(p_cell);
			*trans=p_cell;
			DBG("DEBUG: t_lookup_ident: transaction found\n");
			return 1;
		}
    }
	
	UNLOCK_HASH(hash_index);
	set_t(0);
	*trans=p_cell;

	DBG("DEBUG: t_lookup_ident: transaction not found\n");
    
    return -1;
}
Пример #3
0
static inline void cond_t(int cond)
{
    if (cond)
        set_t();
    else
        clr_t();
}
Пример #4
0
 ParamPolicy_3<P1, P2, P3>::ParamPolicy_3(const ParamPolicy_3 &rhs)
     : Model(rhs),
       prm1_(rhs.prm1_->clone()),
       prm2_(rhs.prm2_->clone()),
       prm3_(rhs.prm3_->clone()) {
   set_t();
 }
Пример #5
0
void run_trans_callbacks( int type , struct cell *trans,
						struct sip_msg *req, struct sip_msg *rpl, int code )
{
	struct tmcb_params params;
	struct tm_callback    *cbp;
	struct usr_avp **backup;
	struct cell *trans_backup = get_t();

	params.req = req;
	params.rpl = rpl;
	params.code = code;
	params.extra1 = tmcb_extra1;
	params.extra2 = tmcb_extra2;

	if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
		return;

	backup = set_avp_list( &trans->user_avps );
	for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
		if ( (cbp->types)&type ) {
			LM_DBG("trans=%p, callback type %d, id %d entered\n",
				trans, type, cbp->id );
			params.param = &(cbp->param);
			cbp->callback( trans, type, &params );
		}
	}
	/* env cleanup */
	set_avp_list( backup );
	tmcb_extra1 = tmcb_extra2 = 0;
	set_t(trans_backup);
}
Пример #6
0
static inline int new_t(struct sip_msg *p_msg)
{
	struct cell *new_cell;

	/* for ACK-dlw-wise matching, we want From-tags */
	if (p_msg->REQ_METHOD==METHOD_INVITE && parse_from_header(p_msg)<0) {
			LOG(L_ERR, "ERROR: new_t: no valid From in INVITE\n");
			return E_BAD_REQ;
	}
	/* make sure uri will be parsed before cloning */
	if (parse_sip_msg_uri(p_msg)<0) {
		LOG(L_ERR, "ERROR: new_t: uri invalid\n");
		return E_BAD_REQ;
	}
			
	/* add new transaction */
	new_cell = build_cell( p_msg ) ;
	if  ( !new_cell ){
		LOG(L_ERR, "ERROR: new_t: out of mem:\n");
		return E_OUT_OF_MEM;
	} 

	insert_into_hash_table_unsafe( new_cell, p_msg->hash_index );
	set_t(new_cell);
	INIT_REF_UNSAFE(T);
	/* init pointers to headers needed to construct local
	   requests such as CANCEL/ACK
	*/
	init_new_t(new_cell, p_msg);
	return 1;
}
Пример #7
0
void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
{
	struct tmcb_params params;
	struct tm_callback    *cbp;
	struct usr_avp **backup;
	struct cell *trans_backup = get_t();

	params.req = req;
	params.rpl = 0;
	params.code = code;
	params.extra1 = tmcb_extra1;
	params.extra2 = tmcb_extra2;

	if (req_in_tmcb_hl->first==0)
		return;

	backup = set_avp_list( &trans->user_avps );
	for (cbp=req_in_tmcb_hl->first; cbp; cbp=cbp->next)  {
		LM_DBG("trans=%p, callback type %d, id %d entered\n",
			trans, cbp->types, cbp->id );
		params.param = &(cbp->param);
		cbp->callback( trans, cbp->types, &params );
	}
	set_avp_list( backup );
	tmcb_extra1 = tmcb_extra2 = 0;
	set_t(trans_backup);
}
Пример #8
0
 ParamPolicy_1<P> & ParamPolicy_1<P>::operator=
 (const ParamPolicy_1 &rhs){
   if(&rhs != this){
     prm_ = rhs.prm_->clone();
     set_t();
   }
   return *this;
 }
Пример #9
0
 ParamPolicy_4<P1, P2, P3, P4>::ParamPolicy_4()
   : prm1_(),
     prm2_(),
     prm3_(),
     prm4_()
   {
     set_t();
   }
Пример #10
0
 ParamPolicy_4<P1, P2, P3, P4>::ParamPolicy_4
 (Ptr<P1> p1, Ptr<P2> p2, Ptr<P3> p3, Ptr<P4> p4)
   : prm1_(p1),
     prm2_(p2),
     prm3_(p3),
     prm4_(p4)
 {
     set_t();
 }
Пример #11
0
 ParamPolicy_4<P1, P2, P3, P4>::ParamPolicy_4(const ParamPolicy_4 &rhs)
   : Model(rhs),
     prm1_(rhs.prm1_->clone()),
     prm2_(rhs.prm2_->clone()),
     prm3_(rhs.prm3_->clone()),
     prm4_(rhs.prm4_->clone())
   {
     set_t();
   }
Пример #12
0
inline static void retransmission_handler( struct timer_link *retr_tl )
{
	struct retr_buf* r_buf ;
	enum lists id;

	r_buf = get_retr_timer_payload(retr_tl);
#ifdef EXTRA_DEBUG
	if (r_buf->my_T->damocles) {
		LM_ERR("transaction %p scheduled for deletion and"
			" called from RETR timer\n",r_buf->my_T);
		abort();
	}
#endif

	/* the transaction is already removed from RETRANSMISSION_LIST by timer*/
	/* re-transmission */
	if ( r_buf->activ_type==TYPE_LOCAL_CANCEL
		|| r_buf->activ_type==TYPE_REQUEST ) {
			LM_DBG("retransmission_handler : request resending"
				" (t=%p, %.9s ... )\n", r_buf->my_T, r_buf->buffer.s);
			set_t(r_buf->my_T);
			SEND_BUFFER( r_buf );
			/*if (SEND_BUFFER( r_buf )==-1) {
				reset_timer( &r_buf->fr_timer );
				fake_reply(r_buf->my_T, r_buf->branch, 503 );
				return;
			}*/
			set_t(T_UNDEFINED);
	} else {
			LM_DBG("retransmission_handler : reply resending "
				"(t=%p, %.9s ... )\n", r_buf->my_T, r_buf->buffer.s);
			set_t(r_buf->my_T);
			t_retransmit_reply(r_buf->my_T);
			set_t(T_UNDEFINED);
	}

	id = r_buf->retr_list;
	r_buf->retr_list = id < RT_T2 ? id + 1 : RT_T2;

	retr_tl->timer_list= NULL; /* set to NULL so that set_timer will work */
	set_timer( retr_tl, id < RT_T2 ? id + 1 : RT_T2, 0 );

	LM_DBG("retransmission_handler : done\n");
}
Пример #13
0
int crossings(int x0, int y0, struct coef ray)
{
	int i, x3, y3, w3, n0;
	int d1, d2;
	double t, t1;
	
	n0 = 0;
	
	for (i = 0 ; i < num_points ; ++i) {
		x3 = coefs[i].b * ray.c - coefs[i].c * ray.b;
		y3 = -coefs[i].a * ray.c + coefs[i].c * ray.a;
		w3 = coefs[i].a * ray.b - coefs[i].b * ray.a;

		if (w3 == 0)
			continue;

		x3 /= w3;
		y3 /= w3;

		t = set_t(x0, y0, x0 + 1, y0, x3, y3);

		if (t < 0)
			continue;
		
		t1 = t;
		t = set_t(points[i].x, points[i].y, points[i+1].x, points[i+1].y, x3, y3);
			
		if (t <= 0 || t > 1)
			continue;

		if (t == 1) {
			d1 = ray.a * points[i].x + ray.b * points[i].y + ray.c;
			d2 = ray.a * points[i+2].x + ray.b * points[i+2].y + ray.c;
		
			if ((((d1 > 0) && (d2 > 0)) || ((d1 < 0) && (d2 < 0))))
				continue;
		}

		s[n0++] = t1;
	}

	return n0;
}
Пример #14
0
inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2)
{
	struct cell *ret;
	if (msg->REQ_METHOD==METHOD_CANCEL) {
		ret = t_lookupOriginalT( msg );
		DBG("lookup_original: t_lookupOriginalT returned: %p\n", ret);
		if (ret != T_NULL_CELL) {
			/* The cell is reffed by t_lookupOriginalT, but T is not set.
			So we must unref it before returning. */
			UNREF(ret);
			set_t(T_UNDEFINED);
			return 1;
		}
		set_t(T_UNDEFINED);
	} else {
		LOG(L_WARN, "WARNING: script error t_lookup_cancel() called for non-CANCEL request\n");
	}
	return -1;
}
Пример #15
0
 ParamPolicy_3<P1, P2, P3> &ParamPolicy_3<P1, P2, P3>::operator=(
     const ParamPolicy_3 &rhs) {
   if (&rhs != this) {
     prm1_ = rhs.prm1_->clone();
     prm2_ = rhs.prm2_->clone();
     prm3_ = rhs.prm3_->clone();
     set_t();
   }
   return *this;
 }
Пример #16
0
void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
{
    CPU_FloatU f0, f1;
    f0.l = t0;
    f1.l = t1;

    if (float32_compare(f0.f, f1.f, &env->fp_status) == 1)
	set_t();
    else
	clr_t();
}
Пример #17
0
void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
{
    CPU_DoubleU d0, d1;
    d0.ll = t0;
    d1.ll = t1;

    if (float64_compare(d0.d, d1.d, &env->fp_status) == 1)
	set_t();
    else
	clr_t();
}
Пример #18
0
void helper_fcmp_gt_DT(CPUSH4State *env, float64 t0, float64 t1)
{
    int relation;

    set_float_exception_flags(0, &env->fp_status);
    relation = float64_compare(t0, t1, &env->fp_status);
    if (unlikely(relation == float_relation_unordered)) {
        update_fpscr(env, GETPC());
    } else if (relation == float_relation_greater) {
        set_t(env);
    } else {
        clr_t(env);
    }
}
Пример #19
0
void helper_fcmp_gt_FT(float32 t0, float32 t1)
{
    int relation;

    set_float_exception_flags(0, &env->fp_status);
    relation = float32_compare(t0, t1, &env->fp_status);
    if (unlikely(relation == float_relation_unordered)) {
        update_fpscr(GETPC());
    } else if (relation == float_relation_greater) {
	set_t();
    } else {
	clr_t();
    }
}
Пример #20
0
void BDSimulator::step()
{
    last_reactions_.clear();

    {
        BDPropagator propagator(*model_, *world_, *rng(), dt(), last_reactions_);
        while (propagator())
        {
            ; // do nothing here
        }
    }

    set_t(t() + dt());
    num_steps_++;
}
Пример #21
0
static int script_init( struct sip_msg *foo, void *bar)
{
	/* we primarily reset all private memory here to make sure
	 * private values left over from previous message will
	 * not be used again */
	set_t(T_UNDEFINED);
	reset_cancelled_t();
	reset_e2eack_t();
	/* reset the kr status */
	reset_kr();
	/* reset the static holders for T routes */
	t_on_negative( 0 );
	t_on_reply(0);
	t_on_branch(0);
	return 1;
}
Пример #22
0
int t_unref( struct sip_msg* p_msg  )
{
	enum kill_reason kr;

	if (T==T_UNDEFINED)
		return -1;
	if (T!=T_NULL_CELL) {
		if (p_msg->first_line.type==SIP_REQUEST){
			kr=get_kr();
			if (kr==0 ||(p_msg->REQ_METHOD==METHOD_ACK && !(kr & REQ_RLSD)))
				t_release_transaction(T);
		}
		UNREF( T );
	}
	set_t(T_UNDEFINED);
	return 1;
}
Пример #23
0
int t_unref( struct sip_msg* p_msg  )
{
	enum kill_reason kr;

	if (T==T_UNDEFINED || T==T_NULL_CELL)
		return -1;
	if (p_msg->first_line.type==SIP_REQUEST){
		kr=get_kr();
		if (kr==0 
				||(p_msg->REQ_METHOD==METHOD_ACK && !(kr & REQ_RLSD))) {
			LOG(L_WARN, "WARNING: script writer didn't release transaction\n");
			t_release_transaction(T);
		}
	}
	UNREF( T );
	set_t(T_UNDEFINED);
	return 1;
}
Пример #24
0
inline static int t_check_trans(struct sip_msg* msg, char *foo, char *bar)
{
	struct cell *trans;
	struct cell *bkup;
	int ret;

	if (msg->REQ_METHOD==METHOD_CANCEL) {
		/* parse needed hdrs*/
		if (check_transaction_quadruple(msg)==0) {
			LOG(L_ERR, "ERROR:tm:t_check_trans: too few headers\n");
			return 0; /*drop request!*/
		}
		if (!msg->hash_index)
			msg->hash_index = hash(msg->callid->body,get_cseq(msg)->number);
		/* performe lookup */
		trans = t_lookupOriginalT(  msg );
		if (trans) {
			UNREF( trans );
			return 1;
		} else {
			return -1;
		}
	} else {
		bkup = get_t();
		ret = t_lookup_request( msg , 0);
		if ( (trans=get_t())!=0 ) UNREF(trans);
		set_t( bkup );
		switch (ret) {
			case 1:
				/* transaction found */
				return 1;
			case -2:
				/* e2e ACK found */
				return 1;
			default:
				/* notfound */
				return -1;
		}
	}
	return ret;
}
Пример #25
0
inline static int t_check_trans(struct sip_msg* msg)
{
	struct cell *trans;

	if (msg->REQ_METHOD==METHOD_CANCEL) {
		/* parse needed hdrs*/
		if (check_transaction_quadruple(msg)==0) {
			LM_ERR("too few headers\n");
			return 0; /*drop request!*/
		}
		if (!msg->hash_index)
			msg->hash_index = tm_hash(msg->callid->body,get_cseq(msg)->number);
		/* performe lookup */
		trans = t_lookupOriginalT(  msg );
		return trans?1:-1;
	} else {
		trans = get_t();
		if (trans==NULL)
			return -1;
		if (trans!=T_UNDEFINED)
			return 1;
		switch ( t_lookup_request( msg , 0) ) {
			case 1:
				/* transaction found -> is it local ACK? */
				if (msg->REQ_METHOD==METHOD_ACK)
					return 1;
				/* .... else -> retransmission */
				trans = get_t();
				t_retransmit_reply(trans);
				UNREF(trans);
				set_t(0);
				return 0;
			case -2:
				/* e2e ACK found */
				return 1;
			default:
				/* notfound */
				return -1;
		}
	}
}
Пример #26
0
static int script_init( struct sip_msg *foo, void *bar)
{
	/* we primarily reset all private memory here to make sure
	 * private values left over from previous message will
	 * not be used again */
	set_t(T_UNDEFINED);
	reset_cancelled_t();
	reset_e2eack_t();
	fr_timeout = timer_id2timeout[FR_TIMER_LIST];
	fr_inv_timeout = timer_id2timeout[FR_INV_TIMER_LIST];

	/* reset the kill reason status */
	reset_kr();

	/* reset the static holders for T routes */
	t_on_negative( 0 );
	t_on_reply(0);
	t_on_branch(0);

	return SCB_RUN_ALL;
}
Пример #27
0
bool GillespieSimulator::step(const Real &upto)
{
    if (upto <= t())
    {
        return false;
    }

    if (upto >= next_time())
    {
        step();
        return true;
    }
    else
    {
        // no reaction occurs
        // set_dt(next_time() - upto);
        set_t(upto);
        last_reactions_.clear();
        draw_next_reaction();
        return false;
    }
}
Пример #28
0
 ParamPolicy_3<P1, P2, P3>::ParamPolicy_3(const Ptr<P1> &p1, Ptr<P2> p2,
                                          Ptr<P3> p3)
     : prm1_(p1), prm2_(p2), prm3_(p3) {
   set_t();
 }
Пример #29
0
 ParamPolicy_3<P1, P2, P3>::ParamPolicy_3() : prm1_(), prm2_(), prm3_() {
   set_t();
 }
Пример #30
0
/*  This function is called whenever a reply for our module is received; 
  * we need to register  this function on module initialization;
  *  Returns :   0 - core router stops
  *              1 - core router relay statelessly
  */
int reply_received( struct sip_msg  *p_msg )
{
	int msg_status;
	int last_uac_status;
	int branch;
	int reply_status;
	utime_t timer;
	/* has the transaction completed now and we need to clean-up? */
	branch_bm_t cancel_bitmap;
	struct ua_client *uac;
	struct cell *t;
	struct usr_avp **backup_list;
	unsigned int has_reply_route;

	set_t(T_UNDEFINED);

	/* make sure we know the associated transaction ... */
	if (t_check(p_msg, &branch ) == -1) goto not_found;

	/*... if there is none, tell the core router to fwd statelessly */
	t = get_t();
	if ((t == 0) || (t == T_UNDEFINED)) goto not_found;

	cancel_bitmap=0;
	msg_status=p_msg->REPLY_STATUS;

	uac=&t->uac[branch];
	LM_DBG("org. status uas=%d, uac[%d]=%d local=%d is_invite=%d)\n",
		t->uas.status, branch, uac->last_received, 
		is_local(t), is_invite(t));
	last_uac_status=uac->last_received;
	if_update_stat( tm_enable_stats, tm_rcv_rpls , 1);

	/* it's a cancel which is not e2e ? */
	if ( get_cseq(p_msg)->method_id==METHOD_CANCEL && is_invite(t) ) {
		/* ... then just stop timers */
		reset_timer( &uac->local_cancel.retr_timer);
		if ( msg_status >= 200 ) {
				reset_timer( &uac->local_cancel.fr_timer);
		}
		LM_DBG("reply to local CANCEL processed\n");
		goto done;
	}

	/* *** stop timers *** */
	/* stop retransmission */
	reset_timer(&uac->request.retr_timer);

	/* stop final response timer only if I got a final response */
	if ( msg_status >= 200 ) {
		reset_timer( &uac->request.fr_timer);
	}

	/* acknowledge negative INVITE replies (do it before detailed
	 * on_reply processing, which may take very long, like if it
	 * is attempted to establish a TCP connection to a fail-over dst */
	if (is_invite(t) && ((msg_status >= 300) ||
	(is_local(t) && !no_autoack(t) && msg_status >= 200) )) {
		if (send_ack(p_msg, t, branch)!=0)
			LM_ERR("failed to send ACK (local=%s)\n", is_local(t)?"yes":"no");
	}

	_tm_branch_index = branch;

	/* processing of on_reply block */
	has_reply_route = (t->on_reply) || (t->uac[branch].on_reply);
	if (has_reply_route) {
		if (onreply_avp_mode) {
			/* lock the reply*/
			LOCK_REPLIES( t );
			/* set the as avp_list the one from transaction */
			backup_list = set_avp_list(&t->user_avps);
		} else {
			backup_list = 0;
		}
		/* transfer transaction flag to branch context */
		p_msg->flags = t->uas.request->flags;
		setb0flags(t->uac[branch].br_flags);
		/* run block - first per branch and then global one */
		if ( t->uac[branch].on_reply &&
		(run_top_route(onreply_rlist[t->uac[branch].on_reply].a,p_msg)
		&ACT_FL_DROP) && (msg_status<200) ) {
			if (onreply_avp_mode) {
				UNLOCK_REPLIES( t );
				set_avp_list( backup_list );
			}
			LM_DBG("dropping provisional reply %d\n", msg_status);
			goto done;
		}
		if ( t->on_reply && (run_top_route(onreply_rlist[t->on_reply].a,p_msg)
		&ACT_FL_DROP) && (msg_status<200) ) {
			if (onreply_avp_mode) {
				UNLOCK_REPLIES( t );
				set_avp_list( backup_list );
			}
			LM_DBG("dropping provisional reply %d\n", msg_status);
			goto done;
		}
		/* transfer current message context back to t */
		t->uac[branch].br_flags = getb0flags();
		t->uas.request->flags = p_msg->flags;
		if (onreply_avp_mode)
			/* restore original avp list */
			set_avp_list( backup_list );
	}

	if (!onreply_avp_mode || !has_reply_route)
		/* lock the reply*/
		LOCK_REPLIES( t );

	/* mark that the UAC received replies */
	uac->flags |= T_UAC_HAS_RECV_REPLY;

	/* we fire a cancel on spot if (a) branch is marked "to be canceled" or (b)
	 * the whole transaction was canceled (received cancel) and no cancel sent
	 * yet on this branch; and of course, only if a provisional reply :) */
	if (t->uac[branch].flags&T_UAC_TO_CANCEL_FLAG ||
	((t->flags&T_WAS_CANCELLED_FLAG) && !t->uac[branch].local_cancel.buffer.s)) {
		if ( msg_status < 200 )
			/* reply for an UAC with a pending cancel -> do cancel now */
			cancel_branch(t, branch);
		/* reset flag */
		t->uac[branch].flags &= ~(T_UAC_TO_CANCEL_FLAG);
	}

	if (is_local(t)) {
		reply_status = local_reply(t,p_msg, branch,msg_status,&cancel_bitmap);
		if (reply_status == RPS_COMPLETED) {
			cleanup_uac_timers(t);
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);
			/* There is no need to call set_final_timer because we know
			 * that the transaction is local */
			put_on_wait(t);
		}
	} else {
		reply_status = relay_reply(t,p_msg,branch,msg_status,&cancel_bitmap);
		/* clean-up the transaction when transaction completed */
		if (reply_status == RPS_COMPLETED) {
			/* no more UAC FR/RETR (if I received a 2xx, there may
			 * be still pending branches ...
			 */
			cleanup_uac_timers(t);
			if (is_invite(t)) cancel_uacs(t, cancel_bitmap);
			/* FR for negative INVITES, WAIT anything else */
			/* set_final_timer(t); */
		}
	}
	
	if (reply_status!=RPS_PROVISIONAL)
		goto done;
	
	/* update FR/RETR timers on provisional replies */
	if (msg_status < 200 && (restart_fr_on_each_reply ||
	((last_uac_status<msg_status) &&
	((msg_status >= 180) || (last_uac_status == 0)))
	) ) { /* provisional now */
		if (is_invite(t)) {
			/* invite: change FR to longer FR_INV, do not
			 * attempt to restart retransmission any more
			 */
			backup_list = set_avp_list(&t->user_avps);
			if (!fr_inv_avp2timer(&timer)) {
				LM_DBG("FR_INV_TIMER = %lld\n", timer);
				set_timer(&uac->request.fr_timer,
					FR_INV_TIMER_LIST, &timer);
			} else {
				set_timer(& uac->request.fr_timer, FR_INV_TIMER_LIST, 0);
			}
			set_avp_list(backup_list);
		} else {
			/* non-invite: restart retransmissions (slow now) */
			uac->request.retr_list = RT_T2;
			set_timer(&uac->request.retr_timer, RT_T2, 0);
		}
	} /* provisional replies */
	
done:
	/* we are done with the transaction, so unref it - the reference
	 * was incremented by t_check() function -bogdan*/
	t_unref(p_msg);
	/* don't try to relay statelessly neither on success
	 * (we forwarded statefully) nor on error; on troubles, 
	 * simply do nothing; that will make the other party to 
	 * retransmit; hopefuly, we'll then be better off 
	 */
	_tm_branch_index = 0;
	return 0;
not_found:
	set_t(T_UNDEFINED);
	return 1;
}