Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
Archivo: dialog.c Proyecto: ryzhov/ATS0
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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
Archivo: dialog.c Proyecto: ryzhov/ATS0
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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, &param->pvn.u.isname.name.s, &param->pvv, 1)!=0)
		return pv_get_null(msg, param, res);

	res->flags = PV_VAL_STR;
	res->rs = param->pvv;
	return 0;
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
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, &param->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, &param->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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
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);
	}
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
/* 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;
}