Пример #1
0
/**
 * enforce a response coming from a UE to contain the same Via headers sent in the corresponding request
 * @param rpl - the SIP reply
 * @param str1 - not used
 * @param str2 - not used
 * @returns true if ok, false if not or error
 */
int P_enforce_via_list(struct sip_msg *rpl,char *str1, char *str2)
{
	static struct hdr_field * h = NULL;
	str hdr;

	cscf_del_all_headers(rpl, HDR_VIA_T);

	struct sip_msg *req = cscf_get_request_from_reply(rpl);
	
	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_via_list: No transactional request found.\n");
		return CSCF_RETURN_FALSE;
	
	}

	h = cscf_get_next_via_hdr(req,0);
	while (h)
	{
		hdr.len = h->body.len + via_hdr_s.len + via_hdr_e.len;
		hdr.s = pkg_malloc(hdr.len);
		if (!hdr.s)
		{
			LOG(L_ERR, "ERR:"M_NAME":P_enforce_via_list: cannot alloc bytes : %d", hdr.len);
		}
		hdr.len=0;
		STR_APPEND(hdr, via_hdr_s);
		STR_APPEND(hdr, h->body);
		STR_APPEND(hdr, via_hdr_e);
		cscf_add_header_first(rpl, &hdr, HDR_VIA_T);
		h = cscf_get_next_via_hdr(req,h);
	}
	
	return CSCF_RETURN_TRUE;
}
Пример #2
0
/**
 * Inserts the Route header containing the Service-Route to be enforced
 * @param msg - the SIP message to add to
 * @param str1 - the value to insert (IBCF URI here) - !!! quoted if needed
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok or #CSCF_RETURN_ERROR on error
 */
int P_route_to_IBCF(struct sip_msg *msg,char *str1,char*str2)
{
	str newuri={0,0};
	str uri;
	str x;
	int add_lr=0;
	static str lr_param={";lr",3};

	/* Get char *str1 into str uri */
	uri.s = str1;
	uri.len = strlen(str1);

	x.len = route_s.len + uri.len + route_e.len;
	/* Add ;lr if there's not in the URI */
	if (!strstr(str1,";lr")){
		add_lr=1;
		x.len+=lr_param.len;
	}

	x.s = pkg_malloc(x.len);
	if (!x.s){
		LOG(L_ERR, "ERR:"M_NAME":P_route_to_IBCF: Error allocating %d bytes\n",x.len);
		x.len=0;
		return CSCF_RETURN_ERROR;
	}
	
	/* Get complete Route header into x */
	x.len=0;
	STR_APPEND(x,route_s);
	STR_APPEND(x,uri);
	if (add_lr)
		STR_APPEND(x,lr_param);
	STR_APPEND(x,route_e);

	/* Set dst_uri to the topmost Route URI */
	newuri.s = pkg_malloc(uri.len);
	if (!newuri.s){
		LOG(L_ERR, "ERR:"M_NAME":P_route_to_IBCF: Error allocating %d bytes\n",uri.len);
		return CSCF_RETURN_ERROR;
	}
	newuri.len = uri.len;
	memcpy(newuri.s,uri.s,newuri.len);
	if (msg->dst_uri.s)
		pkg_free(msg->dst_uri.s);
	msg->dst_uri = newuri;

	/* Add those Route header in x into msg */
	if (cscf_add_header_first(msg,&x,HDR_ROUTE_T))
		return CSCF_RETURN_TRUE;
	else {
		LOG(L_ERR,"ERR:"M_NAME":P_route_to_IBCF: Failed to add new Route.\n");
		if (x.s) pkg_free(x.s);
		return CSCF_RETURN_ERROR;
	}

}
Пример #3
0
/**
 * Record routes, with given user as parameter.
 * @param msg - the SIP message to add to
 * @param str1 - direction - "orig" or "term"
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not or #CSCF_RETURN_BREAK on error
 */ 
int S_record_route(struct sip_msg *msg,char *str1,char *str2)
{
	str rr={0,0};
	str u = {0,0},scheme={0,0},scscf={0,0};
	
	enum s_dialog_direction dir = get_dialog_direction(str1);
	
	switch (dir){
		case DLG_MOBILE_ORIGINATING:
			STR_PKG_DUP(rr,scscf_record_route_mo,"pkg");
			break;
		case DLG_MOBILE_TERMINATING:
			STR_PKG_DUP(rr,scscf_record_route_mt,"pkg");
			break;
		default:
			u.s = str1;
			u.len = strlen(str1);
			if (scscf_name_str.len>4 &&
				strncasecmp(scscf_name_str.s,"sip:",4)==0){
				scheme.s = scscf_name_str.s;
				scheme.len = 4;
			}else if (scscf_name_str.len>5 &&
				strncasecmp(scscf_name_str.s,"sips:",5)==0){
				scheme.s = scscf_name_str.s;
				scheme.len = 4;
			}
			scscf.s = scheme.s+scheme.len;
			scscf.len = scscf_name_str.len - scheme.len;
			
			rr.len = s_record_route_s.len+scheme.len+u.len+1+scscf.len+s_record_route_e.len;
			rr.s = pkg_malloc(rr.len);
			if (!rr.s){
				LOG(L_ERR,"ERR:"M_NAME":S_record_route: error allocating %d bytes!\n",rr.len);	
				return CSCF_RETURN_BREAK;
			}
			rr.len = 0;
			STR_APPEND(rr,s_record_route_s);
			STR_APPEND(rr,scheme);
			STR_APPEND(rr,u);
			rr.s[rr.len++]='@';
			STR_APPEND(rr,scscf);
			STR_APPEND(rr,s_record_route_e);					
	}
	
	if (cscf_add_header_first(msg,&rr,HDR_RECORDROUTE_T)) return CSCF_RETURN_TRUE;
	else{
		if (rr.s) pkg_free(rr.s);
		return CSCF_RETURN_BREAK;
	}
	
out_of_memory:
	return CSCF_RETURN_BREAK;	
}
Пример #4
0
/**
 * Enforce a response coming from a UE to contain the same Record Route headers sent in the
 * corresponding request.
 * @param msg - the SIP reply
 * @param str1 - not used
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE on success, #CSCF_RETURN_ERROR on error
 */
int P_enforce_record_routes(struct sip_msg *msg,char *str1, char *str2)
{
	str hdr = {0,0};
	str rr_req = {0,0};
	struct sip_msg *req = cscf_get_request_from_reply(msg);

	LOG(L_INFO,"INF:"M_NAME":P_enforce_record_routes(): Enforcing RR in %d reply with the request ones\n",
			msg->first_line.u.reply.statuscode);

	if (!req){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): No transactional request found.\n");
		return CSCF_RETURN_ERROR;
	}
	
	if(!cscf_del_all_headers(msg, HDR_RECORDROUTE_T)){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): error while deleting headers\n");
		return CSCF_RETURN_ERROR;
	}
	
	rr_req = cscf_get_record_routes(req);
	if(rr_req.len){
		hdr.len = pcscf_record_route_mt.len + s_record_route_s.len + rr_req.len+s_record_route_e.len;
		if(!(hdr.s = pkg_malloc(hdr.len))){
		    LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to allocate memory for hdr\n");
		    goto out_of_memory;
		}
		hdr.len = 0;
		STR_APPEND(hdr,pcscf_record_route_mt);
		STR_APPEND(hdr,s_record_route_s);
		STR_APPEND(hdr,rr_req);
		STR_APPEND(hdr,s_record_route_e);		
	}else{		
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to get record routes - the RR should not be empty...\n");
		// still, let it continue, maybe it was empty on purpose
		//return CSCF_RETURN_ERROR;
		STR_PKG_DUP(hdr,pcscf_record_route_mt,"pkg");
	}
	
	if(!cscf_add_header_first(msg,&hdr,HDR_RECORDROUTE_T)){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_record_routes(): Unable to add header\n");
		if (hdr.s) pkg_free(hdr.s);
		return CSCF_RETURN_FALSE;
	}

	return CSCF_RETURN_TRUE;
	
out_of_memory:
	return CSCF_RETURN_ERROR;
}
Пример #5
0
int I_scscf_select(struct sip_msg* msg, char* str1, char* str2)
{
	str call_id,scscf_name={0,0};
	struct sip_msg *req;
	int result;
	str hdr={0,0};

	//print_scscf_list(L_ERR);
		
	call_id = cscf_get_call_id(msg,0);
	LOG(L_DBG,"DBG:"M_NAME":I_scscf_select(): <%.*s>\n",call_id.len,call_id.s);
	if (!call_id.len)
		return CSCF_RETURN_FALSE;
	
	scscf_name = take_scscf_entry(call_id);
	if (!scscf_name.len){
		I_scscf_drop(msg,str1,str2);
		cscf_reply_transactional(msg,600,MSG_600_FORWARDING_FAILED);			
		return CSCF_RETURN_BREAK;
	}
	
	if (msg->first_line.u.request.method.len==8 &&
		strncasecmp(msg->first_line.u.request.method.s,"REGISTER",8)==0) {
		/* REGISTER fwding */			
		if (str1&&str1[0]=='0'){
			/* first time */	
			//LOG(L_CRIT,"rewrite uri\n");
			if (rewrite_uri(msg, &(scscf_name)) < 0) {
				LOG(L_ERR,"ERR:"M_NAME":I_UAR_forward: Unable to Rewrite URI\n");
				result = CSCF_RETURN_FALSE;
			}else
				result = CSCF_RETURN_TRUE;
		}else{
			/* subsequent */
			//LOG(L_CRIT,"append branch\n");
			req = msg;//cscf_get_request_from_reply(msg);
			append_branch(req,scscf_name.s,scscf_name.len,0,0,0,0);
			result = CSCF_RETURN_TRUE;
		}
	}else{
		/* Another request */
		result = CSCF_RETURN_TRUE;
		
		hdr.len = route_hdr_s.len+scscf_name.len+route_hdr_e.len;
		hdr.s = pkg_malloc(hdr.len);
		if (!hdr.s){
			LOG(L_ERR,"ERR:"M_NAME":Mw_REQUEST_forward: Error allocating %d bytes\n",
				hdr.len);
			result = CSCF_RETURN_TRUE;
		}
		hdr.len=0;
		STR_APPEND(hdr,route_hdr_s);
		STR_APPEND(hdr,scscf_name);
		STR_APPEND(hdr,route_hdr_e);
	
		if (!cscf_add_header_first(msg,&hdr,HDR_ROUTE_T)){
			pkg_free(hdr.s);
			result = CSCF_RETURN_TRUE;
		}
		
		if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);	
		STR_PKG_DUP(msg->dst_uri,scscf_name,"pkg");
	}

	if (scscf_name.s) shm_free(scscf_name.s);
	return result;
out_of_memory:	
	if (scscf_name.s) shm_free(scscf_name.s);
	return CSCF_RETURN_ERROR;
}
Пример #6
0
/**
 * Inserts the Route header containing the dialog routes to be enforced
 * @param msg - the SIP message to add to
 * @param str1 - the value to insert - !!! quoted if needed
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if ok, #CSCF_RETURN_FALSE if not or #CSCF_RETURN_BREAK on error 
 */
int P_enforce_dialog_routes(struct sip_msg *msg,char *str1,char*str2)
{
	int i;
	str newuri={0,0};
	p_dialog *d;
	str call_id,host;
	int port,transport;
	str x;
	enum p_dialog_direction dir;
	
	dir = get_dialog_direction(str1);
		
	if (!find_dialog_contact(msg,dir,&host,&port,&transport)){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_dialog_routes(): Error retrieving %s contact\n",str1);
		return CSCF_RETURN_BREAK;
	}		
		
	call_id = cscf_get_call_id(msg,0);
	if (!call_id.len)
		return CSCF_RETURN_FALSE;

	LOG(L_INFO,"DBG:"M_NAME":P_enforce_dialog_routes(%s): Call-ID <%.*s> %d://%.*s:%d\n",
		str1,call_id.len,call_id.s,
		transport,host.len,host.s,port);

	d = get_p_dialog(call_id,host,port,transport,&dir);
	if (!d)
		d = get_p_dialog(call_id,host,port,transport,0);
	if (!d){
		LOG(L_ERR,"ERR:"M_NAME":P_enforce_dialog_routes: dialog does not exists!\n");	
		return CSCF_RETURN_FALSE;
	}

	if (!d->routes_cnt){
		d_unlock(d->hash);
		return CSCF_RETURN_TRUE;
	}

	x.len = route_s.len + route_e.len + (d->routes_cnt-1)*route_1.len;
	for(i=0;i<d->routes_cnt;i++)
		x.len+=d->routes[i].len;
			
	x.s = pkg_malloc(x.len);
	if (!x.s){
		LOG(L_ERR, "ERR:"M_NAME":P_enforce_dialog_routes: Error allocating %d bytes\n",
			x.len);
		x.len=0;
		d_unlock(d->hash);
		return CSCF_RETURN_ERROR;
	}
	x.len=0;
	STR_APPEND(x,route_s);
	for(i=0;i<d->routes_cnt;i++){
		if (i) STR_APPEND(x,route_1);
		STR_APPEND(x,d->routes[i]);
	}	
	STR_APPEND(x,route_e);
	
	newuri.s = pkg_malloc(d->routes[0].len);
	if (!newuri.s){
		LOG(L_ERR, "ERR:"M_NAME":P_enforce_dialog_routes: Error allocating %d bytes\n",
			d->routes[0].len);
		d_unlock(d->hash);
		return CSCF_RETURN_ERROR;
	}
	newuri.len = d->routes[0].len;
	memcpy(newuri.s,d->routes[0].s,newuri.len);
	if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);
	msg->dst_uri = newuri;
	
	//LOG(L_ERR,"%.*s",x.len,x.s);
	d_unlock(d->hash);
	if (cscf_add_header_first(msg,&x,HDR_ROUTE_T)) {
		if (cscf_del_all_headers(msg,HDR_ROUTE_T))
			return CSCF_RETURN_TRUE;
		else {
			LOG(L_ERR,"ERR:"M_NAME":P_enforce_dialog_routes: new Route headers added, but failed to drop old ones.\n");
			return CSCF_RETURN_ERROR;
		}
	}
	else {
		if (x.s) pkg_free(x.s);
		return CSCF_RETURN_ERROR;
	}
}