Пример #1
0
/**
 * Alters the saved dlg_t routes for the dialog by removing
 * the first routes before myself.
 * This is requiered because half of the RRset is useless.
 * @param d - the dialog to modify the Record-Routes
 * @param dir - the direction
 */
void alter_dialog_route_set(dlg_t *d,enum s_dialog_direction dir)
{
	rr_t *r,*r_new;	
	str p; /*this is going to point to the scscf uri*/
			
	switch (dir) {
		case DLG_MOBILE_ORIGINATING:
			p = scscf_record_route_mo_uri;
			break;
		case DLG_MOBILE_TERMINATING:
			p = scscf_record_route_mt_uri;
			break;
		default:
			return;
	}
		
	for(r=d->route_set;r!=NULL;r=r->next) {
		if (r->nameaddr.uri.len>=p.len && 
			strncasecmp(r->nameaddr.uri.s,p.s,r->nameaddr.uri.len)==0) {
			r_new = r->next;
			r->next = NULL;
			shm_free_rr(&d->route_set);
			d->route_set = r_new;				
			return;
		}			
	}	
}
Пример #2
0
int preset_dialog_route(dlg_t* dialog, str *route)
{
	rr_t *old_r, *r = NULL;
	int res;

	/* check parameters */
	if ((!dialog) || (is_str_empty(route))) {
		ERR("bad parameters\n");
		return -1;
	}
	if (dialog->state != DLG_NEW) {
		ERR("Dialog is not in DLG_NEW state\n");
		return -1;
	}
	
	if (parse_rr_body(route->s, route->len, &r) < 0) {
		ERR("can't parse given route\n");
		return -1;
	}

	if (!r) {
		ERR("empty route\n");
		return -1;
	}

	old_r = dialog->route_set;
	dialog->route_set = NULL;
	res = shm_duplicate_rr(&dialog->route_set, r);
	if (r) free_rr(&r);
	if (res < 0) {
		/* return old routeset to its place */
		dialog->route_set = old_r;
		ERR("can't duplicate route\n");
		return -1;
	}
	
	/* free old route */
	if (old_r) shm_free_rr(&old_r);

	res = tmb.calculate_hooks(dialog);
	if (res < 0) {
		ERR("Error while calculating hooks\n");
		return -2;
	}

	return 0;
}
Пример #3
0
/*
 * Destroy a dialog state
 */
void free_dlg(dlg_t* _d)
{
        if (!_d) return;

	if (_d->id.call_id.s) shm_free(_d->id.call_id.s);
	if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s);
	if (_d->id.loc_tag.s) shm_free(_d->id.loc_tag.s);

	if (_d->loc_uri.s) shm_free(_d->loc_uri.s);
	if (_d->rem_uri.s) shm_free(_d->rem_uri.s);
	if (_d->rem_target.s) shm_free(_d->rem_target.s);
	if (_d->dst_uri.s) shm_free(_d->dst_uri.s);

	     /* Free all routes in the route set */
	shm_free_rr(&_d->route_set);
	shm_free(_d);
}
Пример #4
0
/**
 * Alters the saved dlg_t routes for the dialog by removing
 * @param d - the dialog to modify the Record-Routes
 * @param dir - the direction
 */
void alter_dialog_route_set(dlg_t *d,enum p_dialog_direction dir,enum release_call_situation situation)
{
	rr_t *r;
	rr_t *r_new;
		
	str p; /*this is going to point to the scscf uri*/
		
		
	

	switch (dir) {
		case DLG_MOBILE_ORIGINATING:
			p = pcscf_record_route_mo_uri;
			
			break;
		case DLG_MOBILE_TERMINATING:
			p = pcscf_record_route_mt_uri;
	
			break;
		default:
			return;
	}
	d->route_set=revert_route(d->route_set);
		
	//LOG(L_CRIT,"Looking for <%.*s> in\n",p.len,p.s);
	//for(r=d->route_set;r!=NULL;r=r->next) 
		//LOG(L_CRIT,"<%.*s>\n",r->nameaddr.uri.len,r->nameaddr.uri.s);
	
		
	for(r=d->route_set;r!=NULL;r=r->next) {
		if (r->nameaddr.uri.len>=p.len && 
			strncasecmp(r->nameaddr.uri.s,p.s,r->nameaddr.uri.len)==0)
			{
				r_new=r->next;
				r->next=NULL;
				shm_free_rr(&d->route_set);
				d->route_set = r_new;
  	            return;
  	            
  	          	
  	            	
			}
				
	}
		
}		
Пример #5
0
/*
 * Extract all necessary information from a response and put it
 * in a dialog structure
 */
static inline int response2dlg(struct sip_msg* _m, dlg_t* _d)
{
	str contact, rtag;
	rtag.s=0;

	     /* Parse the whole message, we will need all Record-Route headers */
	if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
		LOG(L_ERR, "response2dlg(): Error while parsing headers\n");
		return -1;
	}
	
	if (get_contact_uri(_m, &contact) < 0) return -2;
	if (_d->rem_target.s) {
		shm_free(_d->rem_target.s);
		_d->rem_target.s = 0; 
		_d->rem_target.len = 0;
	}
	if (_d->dst_uri.s) {
		shm_free(_d->dst_uri.s);
		_d->dst_uri.s = 0; 
		_d->dst_uri.len = 0;
	}
	if (contact.len && str_duplicate(&_d->rem_target, &contact) < 0) return -3;
	
	if (get_to_tag(_m, &rtag) < 0) goto err1;
	//Its unlikely needed to update the tag with responses but for some reason i do it
	if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s); 
	
	if (rtag.len && str_duplicate(&_d->id.rem_tag, &rtag) < 0) goto err1;
	
	if (_d->route_set) shm_free_rr(&_d->route_set);
	if (get_route_set(_m, &_d->route_set, REVERSE_ORDER) < 0) goto err2;

	return 0;
 err2:
	if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s);
	_d->id.rem_tag.s = 0;
	_d->id.rem_tag.len = 0;

 err1:
	if (_d->rem_target.s) shm_free(_d->rem_target.s);
	_d->rem_target.s = 0;
	_d->rem_target.len = 0;
	return -4;
}
Пример #6
0
/*
 * Destroy a dialog state
 */
void free_dlg(dlg_t* _d)
{
        if (!_d) return;
#ifdef DIALOG_CALLBACKS
	destroy_trans_dlg_callbacks(_d);
#endif
	if (_d->id.call_id.s) shm_free(_d->id.call_id.s);
	if (_d->id.rem_tag.s) shm_free(_d->id.rem_tag.s);
	if (_d->id.loc_tag.s) shm_free(_d->id.loc_tag.s);

	if (_d->loc_uri.s) shm_free(_d->loc_uri.s);
	if (_d->rem_uri.s) shm_free(_d->rem_uri.s);
	if (_d->rem_target.s) shm_free(_d->rem_target.s);
	if (_d->dst_uri.s) shm_free(_d->dst_uri.s);

	     /* Free all routes in the route set */
	shm_free_rr(&_d->route_set);
	shm_free(_d);
}
Пример #7
0
/*
 * Create a copy of route set either in normal or reverse order
 */
static inline int get_route_set(struct sip_msg* _m, rr_t** _rs, unsigned char _order)
{
	struct hdr_field* ptr;
	rr_t* last, *p, *t;
	
	last = 0;

	ptr = _m->record_route;
	while(ptr) {
		if (ptr->type == HDR_RECORDROUTE_T) {
			if (parse_rr(ptr) < 0) {
				LOG(L_ERR, "get_route_set(): Error while parsing Record-Route body\n");
				goto error;
			}

			p = (rr_t*)ptr->parsed;
			if (shm_duplicate_rr(&t, p) < 0) {
				LOG(L_ERR, "get_route_set(): Error while duplicating rr_t\n");
				goto error;
			}
			if (!*_rs) *_rs = t;
			if (last) last->next = t;
			last = t;
			while (last->next) last = last->next; /* !!! there may be more routes in one hdr field !!! */

		}
		ptr = ptr->next;
	}
	if ((*_rs) && (_order != NORMAL_ORDER)) {
		/* better to revert the route outside of cycle above */
		*_rs = revert_route(*_rs);
	}
	
	return 0;

 error:
	shm_free_rr(_rs);
	return -1;
}
Пример #8
0
/*
 * Duplicate a single rr_t structure using pkg_malloc or shm_malloc
 */
static inline int do_duplicate_rr(rr_t** _new, rr_t* _r, int _shm, int _first)
{
	int len, ret;
	rr_t* res, *prev, *it;

	if (!_new || !_r) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}
	prev  = NULL;
	*_new = NULL;
	it    = _r;
	while(it)
	{
		if (it->params) {
			len = it->params->name.s + it->params->len - it->nameaddr.name.s;
		} else {
			len = it->nameaddr.len;
		}

		if (_shm) res = shm_malloc(sizeof(rr_t) + len);
		else res = pkg_malloc(sizeof(rr_t) + len);
		if (!res) {
			LM_ERR("no shm memory left\n");
			goto error;
		}
		memcpy(res, it, sizeof(rr_t));

		res->nameaddr.name.s = (char*)res + sizeof(rr_t);
		memcpy(res->nameaddr.name.s, it->nameaddr.name.s, len);

		if (_shm) {
			ret = shm_duplicate_params(&res->params, it->params);
		} else {
			ret = duplicate_params(&res->params, it->params);
		}

		if (ret < 0) {
			LM_ERR("failed to duplicate parameters\n");
			if (_shm) shm_free(res);
			else pkg_free(res);
			goto error;
		}

		xlate_pointers(it, res);

		res->next=NULL;
		if(*_new==NULL)
			*_new = res;

		if (_first)
			return 0;

		if(prev)
			prev->next = res;
		prev = res;
		it = it->next;
	}
	return 0;
error:
	if (_shm) shm_free_rr(_new);
	else free_rr(_new);
	*_new = NULL;
	return -1;
}