void dlg_th_up_onreply(struct cell* t, int type, struct tmcb_params *param) { struct dlg_cell *dlg; dlg = (struct dlg_cell *)(*param->param); if (dlg==0) return; if(dlg_th_onreply(dlg, param->rpl, param->req, 0, DLG_DIR_UPSTREAM) < 0) LM_ERR("Failed to transform the reply for topology hiding\n"); }
static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param) { struct sip_msg *rpl,*req; struct dlg_cell *dlg; int new_state; int old_state; int unref; int event; str mangled_from = {0,0}; str mangled_to = {0,0}; str *req_out_buff; dlg = (struct dlg_cell *)(*param->param); if (shutdown_done || dlg==0) return; rpl = param->rpl; req = param->req; if (type==TMCB_RESPONSE_FWDED) { /* this callback is under transaction lock (by TM), so it is save to operate at write level, but we need to take care on write-read conflicts -bogdan */ if (rpl!=FAKED_REPLY) { if (req->msg_flags & (FL_USE_UAC_FROM | FL_USE_UAC_TO ) ) { req_out_buff = &t->uac[d_tmb.get_branch_index()].request.buffer; if (extract_ftc_hdrs(req_out_buff->s,req_out_buff->len, (req->msg_flags & FL_USE_UAC_FROM )?&mangled_from:0, (req->msg_flags & FL_USE_UAC_TO )?&mangled_to:0,0,0) != 0) { LM_ERR("failed to extract mangled FROM and TO hdrs\n"); mangled_from.len = 0; mangled_from.s = NULL; mangled_to.len = 0; mangled_to.s = NULL; } else { if ((req->msg_flags & FL_USE_UAC_FROM) && (mangled_from.len == 0 || mangled_from.s == NULL)) LM_CRIT("extract_ftc_hdrs ok but no from extracted : [%.*s]\n",req_out_buff->len,req_out_buff->s); if ((req->msg_flags & FL_USE_UAC_TO) && (mangled_to.len == 0 || mangled_to.s == NULL)) LM_CRIT("extract_ftc_hdrs ok but no to extracted : [%.*s]\n",req_out_buff->len,req_out_buff->s); } } push_reply_in_dialog( rpl, t, dlg,&mangled_from,&mangled_to); if((dlg->flags & DLG_FLAG_TOPHIDING) && dlg_th_onreply(dlg, rpl,req, 1, DLG_DIR_UPSTREAM) < 0) LM_ERR("Failed to transform the reply for topology hiding\n"); } else { LM_DBG("dialog replied from script - cannot get callee info\n"); } /* The state does not change, but the msg is mutable in this callback*/ run_dlg_callbacks(DLGCB_RESPONSE_FWDED, dlg, rpl, DLG_DIR_UPSTREAM, 0); return; } if (type==TMCB_TRANS_CANCELLED) { /* only if we did force match the Cancel to the * dialog before ( from the script ) */ if (current_dlg_pointer == NULL) { /* reference and attached to script */ ref_dlg(dlg,1); current_dlg_pointer = t->dialog_ctx; } return; } if (type==TMCB_TRANS_DELETED) event = DLG_EVENT_TDEL; else if (param->code<200) event = DLG_EVENT_RPL1xx; else if (param->code<300) event = DLG_EVENT_RPL2xx; else event = DLG_EVENT_RPL3xx; next_state_dlg( dlg, event, &old_state, &new_state, &unref); if (new_state==DLG_STATE_EARLY && old_state!=DLG_STATE_EARLY) { run_dlg_callbacks(DLGCB_EARLY, dlg, rpl, DLG_DIR_UPSTREAM, 0); if_update_stat(dlg_enable_stats, early_dlgs, 1); return; } if (new_state==DLG_STATE_CONFIRMED_NA && old_state!=DLG_STATE_CONFIRMED_NA && old_state!=DLG_STATE_CONFIRMED ) { LM_DBG("dialog %p confirmed\n",dlg); /* set start time */ dlg->start_ts = (unsigned int)(time(0)); if (0 != insert_dlg_timer( &dlg->tl, dlg->lifetime )) { LM_CRIT("Unable to insert dlg %p [%u:%u] on event %d [%d->%d] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, event, old_state, new_state, dlg->callid.len, dlg->callid.s, dlg->legs[DLG_CALLER_LEG].tag.len, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[callee_idx(dlg)].tag.len, ZSW(dlg->legs[callee_idx(dlg)].tag.s)); } else { /* reference dialog as kept in timer list */ ref_dlg(dlg,1); } if (dlg->flags & DLG_FLAG_PING_CALLER || dlg->flags & DLG_FLAG_PING_CALLEE) { if (0 != insert_ping_timer( dlg)) { LM_CRIT("Unable to insert ping dlg %p [%u:%u] on event %d [%d->%d] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, event, old_state, new_state, dlg->callid.len, dlg->callid.s, dlg->legs[DLG_CALLER_LEG].tag.len, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[callee_idx(dlg)].tag.len, ZSW(dlg->legs[callee_idx(dlg)].tag.s)); } else { /* reference dialog as kept in ping timer list */ ref_dlg(dlg,1); } } /* save the settings to the database, * if realtime saving mode configured- save dialog now * else: the next time the timer will fire the update*/ dlg->flags |= DLG_FLAG_NEW; if ( dlg_db_mode==DB_MODE_REALTIME ) update_dialog_dbinfo(dlg); /* dialog confirmed */ run_dlg_callbacks( DLGCB_CONFIRMED, dlg, rpl, DLG_DIR_UPSTREAM, 0); if (replication_dests) replicate_dialog_created(dlg); if (old_state==DLG_STATE_EARLY) if_update_stat(dlg_enable_stats, early_dlgs, -1); if_update_stat(dlg_enable_stats, active_dlgs, 1); return; } if ( old_state!=DLG_STATE_DELETED && new_state==DLG_STATE_DELETED ) { LM_DBG("dialog %p failed (negative reply)\n", dlg); /*destroy linkers */ destroy_linkers(dlg->profile_links); dlg->profile_links = NULL; /* dialog setup not completed (3456XX) */ run_dlg_callbacks( DLGCB_FAILED, dlg, rpl, DLG_DIR_UPSTREAM, 0); /* do unref */ if (unref) unref_dlg(dlg,unref); if (old_state==DLG_STATE_EARLY) if_update_stat(dlg_enable_stats, early_dlgs, -1); if_update_stat(dlg_enable_stats, failed_dlgs, 1); return; } /* in any other case, check if the dialog state machine requests to unref the dialog */ if (unref) unref_dlg(dlg,unref); return; }