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(); }
/* 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( ¤t_uri.len))) { try_new++; branch_ret=add_uac( t, p_msg, ¤t_uri, (p_msg->dst_uri.len) ? (&p_msg->dst_uri) : ¤t_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; }