⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orig_transaction.c

📁 性能优秀的SIP Proxy
💻 C
字号:
/* * openser osp module.  * * This module enables openser to communicate with an Open Settlement  * Protocol (OSP) server.  The Open Settlement Protocol is an ETSI  * defined standard for Inter-Domain VoIP pricing, authorization * and usage exchange.  The technical specifications for OSP  * (ETSI TS 101 321 V4.1.1) are available at www.etsi.org. * * Uli Abend was the original contributor to this module. *  * Copyright (C) 2001-2005 Fhg Fokus * * This file is part of openser, a free SIP server. * * openser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * openser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "osp_mod.h"#include "osptoolkit.h"#include "orig_transaction.h"#include "sipheader.h"#include "destination.h"#include "usage.h"#include "osp/osp.h"#include "../../sr_module.h"#include "../../locking.h"#include "../../mem/mem.h"#include "../../dset.h"extern int   _max_destinations;extern char* _device_ip;extern char* _device_port;extern OSPTPROVHANDLE _provider;const int FIRST_ROUTE = 1;const int NEXT_ROUTE  = 0;static int loadosproutes(     struct sip_msg* msg, OSPTTRANHANDLE transaction, int expectedDestCount, char* source, char* source_dev, time_t time_ath);static int prepareDestination(struct sip_msg* msg, int isFirst);int requestosprouting(struct sip_msg* msg, char* ignore1, char* ignore2) {	int res;     /* used for function results */	int valid;   /* returncode for this function */	/* parameters for API call */	char osp_source_dev[200];	char e164_source[1000];	char e164_dest [1000];	unsigned int number_callids = 1;	OSPTCALLID* call_ids[number_callids];	unsigned int log_size = 0;	char* detail_log = NULL;	const char** preferred = NULL;	unsigned int dest_count;	OSPTTRANHANDLE transaction = -1;	time_t time_auth;	valid = MODULE_RETURNCODE_FALSE;	time_auth = time(NULL);	dest_count = _max_destinations;	if (0!= (res=OSPPTransactionNew(_provider, &transaction))) {		LOG(L_ERR, "ERROR: osp: Failed to create a new OSP transaction id %d\n",res);	} else if (0 != getFromUserpart(msg, e164_source,sizeof(e164_source))) {		LOG(L_ERR, "ERROR: osp: Failed to extract calling number\n");	} else if (0 != getToUserpart(msg, e164_dest,sizeof(e164_dest))) {		LOG(L_ERR, "ERROR: osp: Failed to extract called number\n");	} else if (0 != getCallId(msg, &(call_ids[0]))) {		LOG(L_ERR, "ERROR: osp: Failed to extract call id\n");	} else if (0 != getSourceAddress(msg,osp_source_dev,sizeof(osp_source_dev))) {		LOG(L_ERR, "ERROR: osp: Failed to extract source address\n");	} else {		LOG(L_INFO,"osp: Requesting OSP authorization and routing for: "			"transaction-handle '%i' \n"			"osp_source '%s' "			"osp_source_port '%s' "			"osp_source_dev '%s' "			"e164_source '%s' "			"e164_dest '%s' "			"call-id '%.*s' "			"dest_count '%i'",			transaction,			_device_ip,			_device_port,			osp_source_dev,			e164_source,			e164_dest,			call_ids[0]->ospmCallIdLen,			call_ids[0]->ospmCallIdVal,			dest_count		);			if (strlen(_device_port) > 0) {			OSPPTransactionSetNetworkIds(transaction,_device_port,"");		}		/* try to request authorization */		res = OSPPTransactionRequestAuthorisation(		transaction,       /* transaction handle */		_device_ip,         /* from the configuration file */		osp_source_dev,    /* source of call, protocol specific */		e164_source,       /* calling number in nodotted e164 notation */		OSPC_E164,		e164_dest,         /* called number */		OSPC_E164,		"",                /* optional username string, used if no number */		number_callids,    /* number of call ids, here always 1 */		call_ids,          /* sized-1 array of call ids */		preferred,         /* preferred destinations, here always NULL */		&dest_count,       /* max destinations, after call dest_count */		&log_size,          /* size allocated for detaillog (next param) 0=no log */		detail_log);       /* memory location for detaillog to be stored */		if (res == 0 && dest_count > 0) {			LOG(L_INFO, "osp: there is %d osp routes, call-id '%.*s', transaction-id '%lld'\n",				dest_count,call_ids[0]->ospmCallIdLen, call_ids[0]->ospmCallIdVal,get_transaction_id(transaction));			record_orig_transaction(msg,transaction,osp_source_dev,e164_source,e164_dest,time_auth);			valid = loadosproutes(msg,transaction,dest_count,_device_ip,osp_source_dev,time_auth);		} else if (res == 0 && dest_count == 0) {			LOG(L_INFO, "osp: there is 0 osp routes, the route is blocked, call-id '%.*s', transaction-id '%lld'\n",				call_ids[0]->ospmCallIdLen,call_ids[0]->ospmCallIdVal,get_transaction_id(transaction));		} else {			LOG(L_ERR, "ERROR: osp: OSPPTransactionRequestAuthorisation returned %i, call-id '%.*s', transaction-id '%lld'\n",				res,call_ids[0]->ospmCallIdLen,call_ids[0]->ospmCallIdVal,get_transaction_id(transaction));		}	}	if (call_ids[0]!=NULL) {		OSPPCallIdDelete(&(call_ids[0]));	}	if (transaction!=-1) {		OSPPTransactionDelete(transaction);	}		return valid;}static int loadosproutes(struct sip_msg* msg, OSPTTRANHANDLE transaction, int expectedDestCount, char* source, char* source_dev, time_t time_auth) {	int result = MODULE_RETURNCODE_TRUE;	int res;	int count;	osp_dest  dests[MAX_DESTS];	osp_dest* dest;		for (count = 0; count < expectedDestCount; count++) {		dest = initDestination(&dests[count]);		if (dest == NULL) {			result = MODULE_RETURNCODE_FALSE;			break;		}		if (count==0) {			res = OSPPTransactionGetFirstDestination(				transaction,				sizeof(dest->validafter),				dest->validafter,				dest->validuntil,				&dest->timelimit,				&dest->sizeofcallid,				(void*)dest->callid,				sizeof(dest->callednumber),				dest->callednumber,				sizeof(dest->callingnumber),				dest->callingnumber,				sizeof(dest->destination),				dest->destination,				sizeof(dest->destinationdevice),				dest->destinationdevice,				&dest->sizeoftoken,				dest->osptoken);		} else {			res = OSPPTransactionGetNextDestination(				transaction,				0,				sizeof(dest->validafter),				dest->validafter,				dest->validuntil,				&dest->timelimit,				&dest->sizeofcallid,				(void*)dest->callid,				sizeof(dest->callednumber),				dest->callednumber,				sizeof(dest->callingnumber),				dest->callingnumber,				sizeof(dest->destination),				dest->destination,				sizeof(dest->destinationdevice),				dest->destinationdevice,				&dest->sizeoftoken,				dest->osptoken);		}				if (res != 0) {			LOG(L_ERR,"ERROR: osp: getDestination %d failed, expected number %d, current count %d\n",res,expectedDestCount,count);			result = MODULE_RETURNCODE_FALSE;			break;		}		OSPPTransactionGetDestNetworkId(transaction,dest->network_id);		strcpy(dest->source,source);		strcpy(dest->sourcedevice,source_dev);		dest->type = OSPC_SOURCE;		dest->tid = get_transaction_id(transaction);		dest->time_auth = time_auth;		LOG(L_INFO,"osp: getDestination %d returned the following information: "		"valid after '%s' "		"valid until '%s' "		"time limit '%i' seconds "		"call-id '%.*s' "		"calling number '%s' "		"called number '%s' "		"destination '%s' "		"network id '%s' "		"bn token size '%i' ",		count, dest->validafter, dest->validuntil, dest->timelimit, dest->sizeofcallid, dest->callid, dest->callingnumber, dest->callednumber, 		dest->destination, dest->network_id, dest->sizeoftoken);	}	/* save destination in reverse order,	 * this way, when we start searching avps the destinations	 * will be in order 	 */	if (result == MODULE_RETURNCODE_TRUE) {		for(count = expectedDestCount -1; count >= 0; count--) {			saveOrigDestination(&dests[count]);		}	}	return result;}int preparefirstosproute(struct sip_msg* msg, char* ignore1, char* ignore2) {	int result = MODULE_RETURNCODE_TRUE;	DBG("osp: Preparing 1st route\n");	result = prepareDestination(msg,FIRST_ROUTE);	return result;}int preparenextosproute(struct sip_msg* msg, char* ignore1, char* ignore2) {	int result = MODULE_RETURNCODE_TRUE;	DBG("osp: Preparing next route\n");	result = prepareDestination(msg,NEXT_ROUTE);	return result;}int prepareallosproutes(struct sip_msg* msg, char* ignore1, char* ignore2) {	int result = MODULE_RETURNCODE_TRUE;	for( result = preparefirstosproute(msg,ignore1,ignore2);	     result == MODULE_RETURNCODE_TRUE;	     result = preparenextosproute(msg,ignore1,ignore2)) {	}	return MODULE_RETURNCODE_TRUE;}int prepareDestination(struct sip_msg* msg, int isFirst) {	int result = MODULE_RETURNCODE_TRUE;	str newuri = {NULL,0};	osp_dest* dest = getNextOrigDestination();	if (dest != NULL) {		rebuildDestionationUri(&newuri, dest->destination, dest->network_id, dest->callednumber);		LOG(L_INFO, "osp: Preparing route to uri '%.*s' for call-id '%.*s' transaction-id '%lld'\n",newuri.len,newuri.s,dest->sizeofcallid,dest->callid,dest->tid);		if (isFirst == FIRST_ROUTE) {			rewrite_uri(msg, &newuri);			addOspHeader(msg,dest->osptoken,dest->sizeoftoken);		} else {			append_branch(msg, &newuri, NULL, NULL, 0, 0, NULL);		}	} else {		DBG("osp: There is no more routes\n");		reportOrigCallSetUpUsage();		/* Terminating call set-up usage will be reported before the proxy replies with		 * '503 - Service Unavailable' and a tm call back updates the term destination code.		 * So, we will do it manually.		 * We may need to make 503 configurable, just in case a user decides to reply with		 * a different code.  Other options - trigger call-set up usage reporting from the cpl		 * (after replying with an error code), or maybe use a different tm callback.		 */		recordEvent(0,503);		reportTermCallSetUpUsage();		result = MODULE_RETURNCODE_FALSE;	}	if (newuri.len > 0) {		pkg_free(newuri.s);	}		return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -