static int w_match_dialog(struct sip_msg *msg) { int backup,i; void *match_param = NULL; struct sip_uri *r_uri; /* dialog already found ? */ if (get_current_dialog()!=NULL) return 1; /* small trick to force SIP-wise matching */ backup = seq_match_mode; seq_match_mode = SEQ_MATCH_FALLBACK; /* See if we can force DID matching, for the case of topo * hiding, where we have the DID as param of the contact */ if (parse_sip_msg_uri(msg)<0) { LM_ERR("Failed to parse request URI\n"); goto sipwise; } if (parse_headers(msg, HDR_ROUTE_F, 0) == -1) { LM_ERR("failed to parse route headers\n"); goto sipwise; } r_uri = &msg->parsed_uri; if (check_self(&r_uri->host,r_uri->port_no ? r_uri->port_no : SIP_PORT, 0) == 1 && msg->route == NULL) { /* Seems we are in the topo hiding case : * we are in the R-URI and there are no other route headers */ for (i=0;i<r_uri->u_params_no;i++) if (r_uri->u_name[i].len == rr_param.len && memcmp(rr_param.s,r_uri->u_name[i].s,rr_param.len)==0) { LM_DBG("We found DID param in R-URI with value of %.*s\n", r_uri->u_val[i].len,r_uri->u_val[i].s); /* pass the param value to the matching funcs */ match_param = (void *)(&r_uri->u_val[i]); } } sipwise: dlg_onroute( msg, NULL, match_param); seq_match_mode = backup; return (get_current_dialog()==NULL)?-1:1; }
static int w_create_dialog2(struct sip_msg *req,char *param) { struct dlg_cell *dlg; struct cell *t; str res = {0,0}; int flags; if (fixup_get_svalue(req, (gparam_p)param, &res) !=0) { LM_ERR("no create dialog flags\n"); return -1; } flags = parse_create_dlg_flags(res); /* is the dialog already created? */ if ( (dlg=get_current_dialog())!=NULL ) { /*Clear current flags before setting new ones*/ dlg->flags &= ~(DLG_FLAG_PING_CALLER | DLG_FLAG_PING_CALLEE | DLG_FLAG_BYEONTIMEOUT); dlg->flags |= flags; return 1; } t = d_tmb.t_gett(); if (dlg_create_dialog( (t==T_UNDEFINED)?NULL:t, req,flags)!=0) return -1; return 1; }
int pv_set_dlg_timeout(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) { struct dlg_cell *dlg; int timeout, db_update = 0, timer_update = 0; if (val==NULL || val->flags & PV_VAL_NULL) { LM_ERR("cannot assign dialog timeout to NULL\n"); return -1; } if (!(val->flags&PV_VAL_INT)){ /* try parsing the string */ if (str2sint(&val->rs, &timeout) < 0) { LM_ERR("assigning non-int value to dialog flags\n"); return -1; } } else { timeout = val->ri; } if (timeout < 0) { LM_ERR("cannot set a negative timeout\n"); return -1; } if ((dlg = get_current_dialog()) != NULL) { dlg_lock_dlg(dlg); dlg->lifetime = timeout; /* update now only if realtime and the dialog is confirmed */ if (dlg->state >= DLG_STATE_CONFIRMED && dlg_db_mode == DB_MODE_REALTIME) db_update = 1; else dlg->flags |= DLG_FLAG_CHANGED; if (dlg->state == DLG_STATE_CONFIRMED_NA || dlg->state == DLG_STATE_CONFIRMED) timer_update = 1; dlg_unlock_dlg(dlg); if (db_update) update_dialog_timeout_info(dlg); if (replication_dests) replicate_dialog_updated(dlg); if (timer_update && update_dlg_timer(&dlg->tl, timeout) < 0) { LM_ERR("failed to update timer\n"); return -1; } } else if (current_processing_ctx) { /* store it until we match the dialog */ ctx_timeout_set( timeout ); } else { LM_CRIT("BUG - no proicessing context found !\n"); return -1; } return 0; }
static int w_unset_dlg_profile(struct sip_msg *msg, char *profile, char *value) { struct dlg_cell *dlg; pv_elem_t *pve = (pv_elem_t *)value; str val_s; if ( (dlg=get_current_dialog())==NULL ) { LM_CRIT("BUG - setting profile from script, but no dialog found\n"); return -1; } if (((struct dlg_profile_table*)profile)->has_value) { if ( pve==NULL || pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; } if ( unset_dlg_profile( dlg, &val_s, (struct dlg_profile_table*)profile) < 0 ) { LM_ERR("failed to unset profile\n"); return -1; } } else { if ( unset_dlg_profile( dlg, NULL, (struct dlg_profile_table*)profile) < 0 ) { LM_ERR("failed to unset profile\n"); return -1; } } return 1; }
static int w_dlg_terminate(struct sip_msg *msg, char *side, char *r) { struct dlg_cell *dlg; str reason = {0, 0}; int n = (int) (long) side; //check if a reason was given if (r) { if (get_str_fparam(&reason, msg, (fparam_t *) r) < 0) { LM_ERR("failed to recover reason parameter\n"); return -1; } } dlg = get_current_dialog(msg); //dlg_get_ctx_dialog(); if (!dlg) { LM_DBG("Unable to find dialog for terminate\n"); return -1; } if (!dlg_terminate(dlg, msg, &reason, n, NULL)) { LM_DBG("Failed to terminate dialog\n"); return -1; } return 1; }
static int w_is_dlg_flag_set(struct sip_msg *msg, char *mask) { struct dlg_cell *dlg; if ( (dlg=get_current_dialog())==NULL ) return -1; return (dlg->user_flags&((unsigned int)(unsigned long)mask))?1:-1; }
int w_fetch_dlg_value(struct sip_msg *msg, char *name, char *result) { struct dlg_cell *dlg; str val; pv_spec_t *sp_dest; int_str res; int avp_name; unsigned short avp_type; script_var_t * sc_var; sp_dest = (pv_spec_t *)result; if ( (dlg=get_current_dialog())==NULL ) return -1; if (fetch_dlg_value( dlg, (str*)name, &val, 0) ) { LM_DBG("failed to fetch dialog value <%.*s>\n", ((str*)name)->len, ((str*)name)->s); return -1; } switch (sp_dest->type) { case PVT_AVP: if (pv_get_avp_name( msg, &(sp_dest->pvp), &avp_name, &avp_type)!=0){ LM_CRIT("BUG in getting AVP name\n"); return -1; } res.s = val; if (add_avp(avp_type|AVP_VAL_STR, avp_name, res)<0){ LM_ERR("cannot add AVP\n"); return -1; } break; case PVT_SCRIPTVAR: if(sp_dest->pvp.pvn.u.dname == 0){ LM_ERR("cannot find svar name\n"); return -1; } res.s = val; sc_var = (script_var_t *)sp_dest->pvp.pvn.u.dname; if(!set_var_value(sc_var, &res, VAR_VAL_STR)){ LM_ERR("cannot set svar\n"); return -1; } break; default: LM_CRIT("BUG: invalid pvar type\n"); return -1; } return 1; }
static int w_reset_dlg_flag(struct sip_msg *msg, char *mask) { struct dlg_cell *dlg; if ( (dlg=get_current_dialog())==NULL ) return -1; dlg->user_flags &= ~((unsigned int)(unsigned long)mask); return 1; }
static int w_tsl_dlg_flag(struct sip_msg *msg, char *_idx, char *_val) { struct dlg_cell *dlg; if ( (dlg=get_current_dialog())==NULL ) return -2; return test_and_set_dlg_flag(dlg, (unsigned long)(void *)_idx, (unsigned long)(void *) _val); }
static int w_set_dlg_flag(struct sip_msg *msg, char *mask) { struct dlg_cell *dlg; if ( (dlg=get_current_dialog())==NULL ) return -1; dlg->user_flags |= (unsigned int)(unsigned long)mask; dlg->flags |= DLG_FLAG_VP_CHANGED; return 1; }
static int w_fix_route_dialog(struct sip_msg *req) { struct dlg_cell *dlg; dlg = get_current_dialog(); if (dlg==NULL) return -1; if (fix_route_dialog( req, dlg )!=0) return -1; return 1; }
static int w_create_dialog(struct sip_msg *req) { struct cell *t; /* is the dialog already created? */ if (get_current_dialog()!=NULL) return 1; t = d_tmb.t_gett(); if (dlg_create_dialog( (t==T_UNDEFINED)?NULL:t, req,0)!=0) return -1; return 1; }
int pv_get_dlg_end_reason(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { struct dlg_cell *dlg; if(msg==NULL || res==NULL) return -1; if ( (dlg=get_current_dialog())==NULL || dlg->terminate_reason.s == NULL) return pv_get_null( msg, param, res); res->rs = dlg->terminate_reason; res->flags = PV_VAL_STR; return 0; }
static int w_validate_dialog(struct sip_msg *req) { struct dlg_cell *dlg; dlg = get_current_dialog(); if (dlg==NULL) { LM_ERR("null dialog\n"); return -1; } if (dlg_validate_dialog( req, dlg )!=0) return -1; return 1; }
static int create_dialog_wrapper(struct sip_msg *req,int flags) { struct cell *t; struct dlg_cell *dlg; /* is the dialog already created? */ if ((dlg = get_current_dialog())!=NULL) { dlg->flags |= flags; return 1; } t = d_tmb.t_gett(); if (dlg_create_dialog( (t==T_UNDEFINED)?NULL:t, req,flags)!=0) return -1; return 1; }
int w_store_dlg_value(struct sip_msg *msg, char *name, char *val) { struct dlg_cell *dlg; pv_elem_t *pve = (pv_elem_t *)val; str val_s; if ( (dlg=get_current_dialog())==NULL ) return -1; if ( pve==NULL || pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; } return (store_dlg_value( dlg, (str*)name, &val_s)==0)?1:-1; }
static int w_match_dialog(struct sip_msg *msg) { int backup; /* dialog already found ? */ if (get_current_dialog()!=NULL) return 1; /* small trick to force SIP-wise matching */ backup = seq_match_mode; seq_match_mode = SEQ_MATCH_FALLBACK; dlg_onroute( msg, NULL, NULL); seq_match_mode = backup; return (current_dlg_pointer==NULL)?-1:1; }
static int w_validate_dialog(struct sip_msg *req) { struct dlg_cell *dlg; int ret; dlg = get_current_dialog(); if (dlg==NULL) { LM_ERR("null dialog\n"); return -4; } ret = dlg_validate_dialog(req,dlg); if (ret == 0) ret = 1; return ret; }
int pv_get_dlg_val(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { struct dlg_cell *dlg; if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL ) { LM_CRIT("BUG - bad parameters\n"); return -1; } if ( (dlg=get_current_dialog())==NULL ) return pv_get_null(msg, param, res); if (fetch_dlg_value( dlg, ¶m->pvn.u.isname.name.s, ¶m->pvv, 1)!=0) return pv_get_null(msg, param, res); res->flags = PV_VAL_STR; res->rs = param->pvv; return 0; }
int pv_set_dlg_flags(struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) { struct dlg_cell *dlg; if ( (dlg=get_current_dialog())==NULL ) return -1; if (val==NULL) { dlg->user_flags = 0; return 0; } if (!(val->flags&PV_VAL_INT)){ LM_ERR("assigning non-int value to dialog flags\n"); return -1; } dlg->user_flags = val->ri; return 0; }
int pv_get_dlg_timeout(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { int l = 0; char *ch = NULL; struct dlg_cell *dlg; if(res==NULL) return -1; if ( (dlg=get_current_dialog())!=NULL ) { dlg_lock_dlg(dlg); if (dlg->state == DLG_STATE_DELETED) l = 0; else if (dlg->state < DLG_STATE_CONFIRMED_NA) l = dlg->lifetime; else l = dlg->tl.timeout - get_ticks(); dlg_unlock_dlg(dlg); } else if (current_processing_ctx) { if ((l=ctx_timeout_get())==0) return pv_get_null( msg, param, res); } else { return pv_get_null( msg, param, res); } res->ri = l; ch = int2str( (unsigned long)res->ri, &l); res->rs.s = ch; res->rs.len = l; res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; return 0; }
int pv_set_dlg_val(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) { struct dlg_cell *dlg; if ( (dlg=get_current_dialog())==NULL ) return -1; if (param==NULL || param->pvn.type!=PV_NAME_INTSTR || param->pvn.u.isname.type!=AVP_NAME_STR || param->pvn.u.isname.name.s.s==NULL ) { LM_CRIT("BUG - bad parameters\n"); return -1; } if (val==NULL || val->flags&(PV_VAL_NONE|PV_VAL_NULL|PV_VAL_EMPTY)) { /* if NULL, remove the value */ if (store_dlg_value( dlg, ¶m->pvn.u.isname.name.s, NULL)!=0) { LM_ERR("failed to delete dialog values <%.*s>\n", param->pvn.u.isname.name.s.len,param->pvn.u.isname.name.s.s); return -1; } } else { /* if value, must be string */ if ( !(val->flags&PV_VAL_STR)) { LM_ERR("non-string values are not supported\n"); return -1; } if (store_dlg_value( dlg, ¶m->pvn.u.isname.name.s, &val->rs)!=0) { LM_ERR("failed to store dialog values <%.*s>\n", param->pvn.u.isname.name.s.len,param->pvn.u.isname.name.s.s); return -1; } } return 0; }
int pv_get_dlg_dir(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { struct dlg_cell *dlg; if(msg==NULL || res==NULL) return -1; if ( (dlg=get_current_dialog())==NULL || last_dst_leg<0) return pv_get_null( msg, param, res); if (last_dst_leg==0) { res->rs.s = "upstream"; res->rs.len = 8; } else { res->rs.s = "downstream"; res->rs.len = 10; } res->flags = PV_VAL_STR; return 0; }
int pv_get_dlg_flags(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { int l = 0; char *ch = NULL; struct dlg_cell *dlg; if(msg==NULL || res==NULL) return -1; if ( (dlg=get_current_dialog())==NULL ) return pv_get_null( msg, param, res); res->ri = dlg->user_flags; ch = int2str( (unsigned long)res->ri, &l); res->rs.s = ch; res->rs.len = l; res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; return 0; }
/* item/pseudo-variables functions */ int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { int l = 0; char *ch = NULL; struct dlg_cell *dlg; if(msg==NULL || res==NULL) return -1; if ( (dlg=get_current_dialog())==NULL ) return pv_get_null( msg, param, res); res->ri = (unsigned int)(dlg->state>2?((time(0))-dlg->start_ts):0); ch = int2str( (unsigned long)res->ri, &l); res->rs.s = ch; res->rs.len = l; res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; return 0; }
int pv_get_dlg_did(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { struct dlg_cell *dlg; str aux; if(msg==NULL || res==NULL) return -1; if ( (dlg=get_current_dialog())==NULL ) return pv_get_null( msg, param, res); res->rs.s = buf_get_did; aux.s = int2str( (unsigned long)dlg->h_entry, &aux.len); if (!aux.s || !aux.len) { LM_ERR("invalid hash entry\n"); return -1; } memcpy(buf_get_did, aux.s, aux.len); buf_get_did[aux.len] = ':'; res->rs.len = aux.len + 1; aux.s = int2str( (unsigned long)dlg->h_id, &aux.len); if (!aux.s || !aux.len) { LM_ERR("invalid hash id\n"); return -1; } memcpy(buf_get_did + res->rs.len, aux.s, aux.len); res->rs.len += aux.len; res->flags = PV_VAL_STR; return 0; }
static int w_is_in_profile(struct sip_msg *msg, char *profile, char *value) { struct dlg_cell *dlg; pv_elem_t *pve = (pv_elem_t *)value; str val_s; if ( (dlg=get_current_dialog())==NULL ) { LM_CRIT("BUG - setting profile from script, but no dialog found\n"); return -1; } if ( pve!=NULL && ((struct dlg_profile_table*)profile)->has_value) { if ( pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; } return is_dlg_in_profile( dlg, (struct dlg_profile_table*)profile, &val_s); } else { return is_dlg_in_profile( dlg, (struct dlg_profile_table*)profile, NULL); } }
int dlg_th_post_raw(str *data) { struct sip_msg msg; struct dlg_cell *dlg; dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ return 0; } memset(&msg,0,sizeof(struct sip_msg)); msg.buf=data->s; msg.len=data->len; if (dlg_th_callid_pre_parse(&msg,1) < 0) goto done; if (msg.first_line.type==SIP_REQUEST) { if (get_to(&msg)->tag_value.len>0) { /* sequential request, check if callid needs to be unmasked */ if (get_from(&msg)->tag_value.len != 0) { if (memcmp(get_from(&msg)->tag_value.s, dlg->legs[0].tag.s,dlg->legs[0].tag.len) == 0) { /* request from caller - need to encode callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to mask callid for initial request\n"); goto error; } goto rebuild_req; } else { /* let request go through - was decoded on the in side */ } } else { /* no from tag in request - kinda foobar ? - let it through */ goto done; } } else { /* initial request, mask callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to mask callid for initial request\n"); goto error; } goto rebuild_req; } } else if (msg.first_line.type==SIP_REPLY) { /* we need to look at the direction */ if (get_from(&msg)->tag_value.len != 0) { if (memcmp(get_from(&msg)->tag_value.s, dlg->legs[0].tag.s,dlg->legs[0].tag.len) == 0) { /* reply going to caller - decode was done on the receiving end, let it unchanged */ } else { /* reply going to callee , need to encode callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to decode callid for reply\n"); goto error; } goto rebuild_rpl; } } else { /* no from tag in reply - kinda foobar ? - let it through */ goto done; } } done: free_sip_msg(&msg); return 0; rebuild_req: data->s = dlg_th_rebuild_req(&msg,&data->len); free_sip_msg(&msg); return 0; rebuild_rpl: data->s = dlg_th_rebuild_rpl(&msg,&data->len); free_sip_msg(&msg); return 0; error: free_sip_msg(&msg); return -1; }
int dlg_th_post_raw(str *data) { struct sip_msg msg; struct dlg_cell *dlg; memset(&msg,0,sizeof(struct sip_msg)); msg.buf=data->s; msg.len=data->len; if (parse_msg(msg.buf,msg.len,&msg)!=0) { LM_ERR("Invalid SIP msg \n"); goto error; } if (parse_headers(&msg,HDR_EOH_F,0)<0) { LM_ERR("Failed to parse SIP headers\n"); goto error; } if (msg.cseq==NULL || get_cseq(&msg)==NULL) { LM_ERR("Failed to parse CSEQ header \n"); goto error; } if((get_cseq(&msg)->method_id)&MSG_SKIP_BITMASK) { LM_DBG("Skipping %d for DLG callid topo hiding\n",get_cseq(&msg)->method_id); goto error; } if (parse_to_header(&msg)<0 || msg.to==NULL || get_to(&msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if (parse_from_header(&msg)<0 || msg.from==NULL || get_from(&msg)==NULL) { LM_ERR("cannot parse TO header\n"); goto error; } if (msg.first_line.type==SIP_REQUEST) { if (get_to(&msg)->tag_value.len>0) { /* sequential request, check if callid needs to be unmasked */ dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ } else { if (get_from(&msg)->tag_value.len != 0) { if (memcmp(get_from(&msg)->tag_value.s, dlg->legs[0].tag.s,dlg->legs[0].tag.len) == 0) { /* request from caller - need to encode callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to mask callid for initial request \n"); goto error; } goto rebuild_req; } else { /* let request go through - was decoded on the in side */ } } else { /* no from tag in request - kinda foobar ? - let it through */ } } } else { /* initial request */ dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ } else { /* mask callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to mask callid for initial request \n"); goto error; } goto rebuild_req; } } } else if (msg.first_line.type==SIP_REPLY) { /* we need to look at the direction */ dlg = get_current_dialog(); if (dlg == NULL || (dlg->flags & DLG_FLAG_TOPH_HIDE_CALLID) == 0 ) { /* dialog module not involved or not callid topo hiding - let is pass freely */ } else { if (get_from(&msg)->tag_value.len != 0) { if (memcmp(get_from(&msg)->tag_value.s, dlg->legs[0].tag.s,dlg->legs[0].tag.len) == 0) { /* reply going to caller - decode was done on the receiving end, let it unchanged */ } else { /* reply going to callee , need to encode callid */ if (dlg_th_encode_callid(&msg) < 0) { LM_ERR("Failed to decode callid for reply \n"); goto error; } goto rebuild_rpl; } } else { /* no from tag in reply - kinda foobar ? - let it through */ } } } free_sip_msg(&msg); return 0; rebuild_req: data->s = dlg_th_rebuild_req(&msg,&data->len); free_sip_msg(&msg); return 0; rebuild_rpl: data->s = dlg_th_rebuild_rpl(&msg,&data->len); free_sip_msg(&msg); return 0; error: free_sip_msg(&msg); return -1; }
/* hide via, route sets and contacts */ static int topology_hiding(struct sip_msg *req,int extra_flags) { struct dlg_cell *dlg; struct hdr_field *it; char* buf; struct lump* lump, *crt, *prev_crt =0, *a, *foo; struct cell* t; t = d_tmb.t_gett(); if (t == T_UNDEFINED) t=NULL; dlg = get_current_dialog(); if(!dlg) { if(dlg_create_dialog( t, req, 0) != 0) { LM_ERR("Failed to create dialog\n"); return -1; } /* double check if the dialog can be retrieved */ if (!(dlg = get_current_dialog())) { LM_ERR("failed to get dialog\n"); return -1; } } dlg->flags |= DLG_FLAG_TOPHIDING; dlg->flags |= extra_flags; /* delete also the added record route and the did param */ for(crt=req->add_rm; crt;) { lump = 0; if(crt->type != HDR_RECORDROUTE_T) /* check on before list for parameters */ for( lump=crt->before ; lump ; lump=lump->before ) { /* we are looking for the lump that adds the * suffix of the RR header */ if ( lump->type==HDR_RECORDROUTE_T && lump->op==LUMP_ADD) { LM_DBG("lump before root %p\n", crt); LM_DBG("Found lump = %p, %.*s\n", lump, lump->len,lump->u.value); break; } } if((crt->type==HDR_RECORDROUTE_T) || lump) { /* lump found */ lump = crt; crt = crt->next; a=lump->before; while(a) { LM_DBG("before [%p], op=%d\n", a, a->op); if(a->op == LUMP_ADD) LM_DBG("value= %.*s\n", a->len, a->u.value); foo=a; a=a->before; if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(foo); if (!(foo->flags&LUMPFLAG_SHMEM)) pkg_free(foo); } a=lump->after; while(a) { LM_DBG("after [%p], op=%d\n", a, a->op); if(a->op == LUMP_ADD) LM_DBG("value= %.*s\n", a->len, a->u.value); foo=a; a=a->after; if (!(foo->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(foo); if (!(foo->flags&LUMPFLAG_SHMEM)) pkg_free(foo); } if(lump == req->add_rm) req->add_rm = lump->next; else prev_crt->next = lump->next; if (!(lump->flags&(LUMPFLAG_DUPED|LUMPFLAG_SHMEM))) free_lump(lump); if (!(lump->flags&LUMPFLAG_SHMEM)) pkg_free(lump); // goto after_del_rr; // break; continue; } prev_crt = crt; crt= crt->next; } buf = req->buf; /* delete record-route headers */ for (it=req->record_route;it;it=it->sibling) { if (del_lump(req,it->name.s - buf,it->len,HDR_RECORDROUTE_T) == 0) { LM_ERR("del_lump failed - while deleting record-route\n"); return -1; } } /* delete via headers */ if(dlg_del_vias(req) < 0) { LM_ERR("Failed to remove via headers\n"); return -1; } /* replace contact*/ if(dlg_replace_contact(req, dlg) < 0) { LM_ERR("Failed to replace contact\n"); return -1; } return 1; }