/**
 * Registers tm callback to apply privacy to replies.
 * @param msg - the SIP message
 * @param str1 - not used
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE
 */
int S_privacy_hook(struct sip_msg* msg, char* str1, char* str2) {
	unsigned int a,b;
	
	cscf_get_transaction(msg,&a,&b);
#ifdef SER_MOD_INTERFACE
	tmb.register_tmcb(msg,0,TMCB_RESPONSE_IN,privacy_reply_cb,0,0);
#else
	tmb.register_tmcb(msg,0,TMCB_RESPONSE_IN,privacy_reply_cb,0);
#endif	
	return CSCF_RETURN_TRUE;
}
Exemple #2
0
/**
 *	Forwards the message to the application server.
 * - Marks the message
 * - fills routes
 * - replaces dst_uri
 * @param msg - the SIP message
 * @param m  - the isc_match that matched with info about where to forward it 
 * @param mark  - the isc_mark that should be used to mark the message
 * @returns #ISC_RETURN_TRUE if OK, #ISC_RETURN_ERROR if not
 */
int isc_forward( struct sip_msg *msg, isc_match *m,isc_mark *mark)
{
	struct cell *t;
	unsigned int hash,label;
	ticks_t fr_timeout,fr_inv_timeout;
	DBG( "DEBUG:"M_NAME":isc_forward(): marking for AS <%.*s>\n",
		m->server_name.len, m->server_name.s );

	isc_mark_set(msg,m,mark);
	/* change destination so it forwards to the app server */
	if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);
	msg->dst_uri.s = pkg_malloc(m->server_name.len);
	if (!msg->dst_uri.s) {
		LOG(L_ERR,"ERR:"M_NAME":isc_forward(): error allocating %d bytes\n",m->server_name.len);
		return ISC_RETURN_ERROR;
	}
	msg->dst_uri.len = m->server_name.len;
	memcpy(msg->dst_uri.s,m->server_name.s,m->server_name.len);

	/* append branch if last trigger failed */
	if (*isc_tmb.route_mode == MODE_ONFAILURE) 
		append_branch(msg,msg->first_line.u.request.uri.s,msg->first_line.u.request.uri.len,
			msg->dst_uri.s,msg->dst_uri.len,0,0);
	
	/* set the timeout timers to a lower value */
	cscf_get_transaction(msg,&hash,&label);
	t = isc_tmb.t_gett();
	fr_timeout = t->fr_timeout;
	fr_inv_timeout = t->fr_inv_timeout;
	t->fr_timeout=S_TO_TICKS(isc_fr_timeout)/1000;
	t->fr_inv_timeout=S_TO_TICKS(isc_fr_inv_timeout)/1000;
	
	/* send it */
	isc_tmb.t_relay(msg,0,0);
	
	/* recover the timeouts */
	t->fr_timeout=fr_timeout;
	t->fr_inv_timeout=fr_inv_timeout;
	
	LOG(L_INFO,"INFO:"M_NAME">>       msg was fwded to AS\n");
	
//	LOG(L_INFO,"INFO:"M_NAME":isc_forward:   fw relayed with marking [%8X]\n",rc->mark.cnt);
//	DBG( "DEBUG:"M_NAME":isc_forward: Forward sending finished, resuming operation\n" );
	return ISC_RETURN_TRUE;
}
/* Send the OPTIONS response to the E-CSCF
 * could be used after a LOCSIP NOTIFY is received
 * @param msg  - the OPTIONS request from the ECSCF
 * @param str1 - not used
 * @param str2 - not used
 * @return CSCF_RETURN_TRUE if ok, or CSCF_RETURN_FALSE if error
 */
int LRF_call_query_resp(struct sip_msg* msg, char*str1, char*str2){

	str user_uri;
	user_d * d= NULL;
	str service;
	struct cell * trans = NULL;
	str resp_body = {0,0};
	str headers = {0,0};
	unsigned int hash_index, label;

	LOG(L_INFO, "INFO:"M_NAME":LRF_call_query_resp\n");

	if (msg->first_line.u.request.method.len!=7||
		memcmp(msg->first_line.u.request.method.s,"OPTIONS",7)!=0){
		LOG(L_WARN,"WARN:"M_NAME":LRF_call_query_resp: The method is not an OPTIONS, trying to replace the message\n");

		msg = cscf_get_request_from_reply(NULL);
		if(! msg || msg->first_line.type!=SIP_REQUEST || msg->first_line.u.request.method.len!=7||
			memcmp(msg->first_line.u.request.method.s,"OPTIONS",7)!=0){
					
			LOG(L_ERR,"BUG:"M_NAME":LRF_call_query_resp: The new message is not an OPTIONS request either\n");
			return CSCF_RETURN_ERROR;
		}
	}

	service = cscf_get_headers_content(msg, service_hdr_name);
	if(!service.len || !service.s){
		LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not find the service header in the OPTIONS, or could not be parsed\n");
		return CSCF_RETURN_FALSE;
	}

	str callid = cscf_get_call_id(msg, NULL);
	if(!callid.s || !callid.len){
		LOG(L_ERR, "ERR:"M_NAME":LRF_get_psap: could not find the callid header in the OPTIONS request\n");
		return CSCF_RETURN_FALSE;
	}

	user_uri = msg->first_line.u.request.uri;
	d = get_user_data(user_uri, service, callid);
	if(!d) {
		LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not found user data for uri %.*s and service %.*s\n",
				user_uri.len, user_uri.s, service.len, service.s);
		goto error;
	}

	if(!d->psap_uri.len || !d->psap_uri.s){
		LOG(L_ERR, "ERR: "M_NAME":LRF_call_query_resp: null psap uri\n");
		goto error;
	}

	if(d->loc && d->locsip_loc){
		LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: LRF has location information from the LOCSIP server\n");
		if(get_options_resp_body(&resp_body, d)){
			LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp:could not get the OPTIONS response body\n");
			goto error;
		}
	}
	
	if(get_options_resp_headers(&headers, d)){
		LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp:could not get the OPTIONS response headers\n");
		goto error;
	}
	
	//get crt trans	
	if(cscf_get_transaction(msg, &hash_index, &label)<0){
		LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not get the trans from the message\n");
		goto error;
	}

	if(tmb.t_lookup_ident(&trans, hash_index, label)!=1){
		LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not get the trans from the hash and index\n");
		goto error;
	}
	
	if(tmb.t_reply_with_body(trans, 200, "OK - PSAP found", resp_body.s, headers.s, "lrf" )!= 1){
		LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: could not send the response\n");
		goto error2;
	}

#ifndef TM_DEL_UNREF
	LOG(L_ERR, "ERR:"M_NAME":LRF_call_query_resp: options ref count %i\n", trans->ref_count);
#endif
	

	lrf_unlock(d->hash);
	if(resp_body.s)
		pkg_free(resp_body.s);
	if(headers.s)
		pkg_free(headers.s);

	return CSCF_RETURN_TRUE;

error2:
	//tmb.t_unref_ident(trans->hash_index, trans->label);

error:
	LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n");
	if(d)
		lrf_unlock(d->hash);
	LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n");
	//if(resp_body.s) pkg_free(resp_body.s);
	LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n");
	//if(headers.s)	pkg_free(headers.s);
	LOG(L_DBG, "DBG: "M_NAME":LRF_call_query_resp: error label\n");

	return CSCF_RETURN_FALSE;
}