示例#1
0
文件: session.c 项目: asyn/openvims
/**
 * Initializes the session related structures.
 */
int session_init()
{
	session_lock = lock_alloc();
	if (!session_lock){
		LOG_NO_MEM("lock",sizeof(gen_lock_t));
		goto error;
	}
	session_lock = lock_init(session_lock);
	session_id1 = shm_malloc(sizeof(unsigned int));
	if (!session_id1){
		LOG_NO_MEM("shm",sizeof(unsigned int));
		goto error;
	}
	session_id2 = shm_malloc(sizeof(unsigned int));
	if (!session_id2){
		LOG_NO_MEM("shm",sizeof(unsigned int));
		goto error;
	}
	srand((unsigned int)time(0));	
	*session_id1 = rand();
	*session_id1 <<= 16;
	*session_id1 += time(0)&0xFFFF;
	*session_id2 = 0;
	return 1;
error:
	return 0;
}
示例#2
0
/**
 * Adds a timer to the timer list.
 * @param expires_in - time until expiration in seconds
 * @param one_time - if after expiration it should be removed or kept in the timers list
 * @param cb - callback function to be called on expiration
 * @param ptr - generic pointer to pass to the callback on expiration
 * @returns 1 on success or 0 on failure
 */
int add_timer(int expires_in,int one_time,callback_f cb,void *ptr)
{
	timer_cb_t *n;
	if (expires_in==0){
		LM_ERR("add_timer(): Minimum expiration time is 1 second!\n");
		return 0;
	}
	n = shm_malloc(sizeof(timer_cb_t));
	if (!n){
		LOG_NO_MEM("shm",sizeof(timer_cb_t));
		return 0;
	}
	n->ptr = shm_malloc(sizeof(void*));
	if (!n){
		LOG_NO_MEM("shm",sizeof(void*));
		shm_free(n);
		return 0;
	}
	n->expires = expires_in + time(0);
	n->one_time = one_time;
	//n->interval = expires_in;
	n->cb = cb;
	*(n->ptr) = ptr;

	lock_get(timers_lock);
		n->prev = timers->tail;
		n->next = 0;
		if (!timers->head) timers->head = n;
		if (timers->tail) timers->tail->next = n;
		timers->tail = n;
	lock_release(timers_lock);
	return 1;
}
示例#3
0
/**
 * Create and add a transaction to the transaction list.
 * @param msg - the message that this related to
 * @param cb - callback to be called on response or time-out
 * @param ptr - generic pointer to pass to the callback on call
 * @param timeout - timeout time in seconds
 * @param auto_drop - whether to auto drop the transaction on event, or let the application do it later
 * @returns the created cdp_trans_t* or NULL on error 
 */
inline cdp_trans_t* cdp_add_trans(AAAMessage *msg,AAATransactionCallback_f *cb, void *ptr,int timeout,int auto_drop)
{
	cdp_trans_t *x;
	x = shm_malloc(sizeof(cdp_trans_t));
	if (!x) {
		LOG_NO_MEM("shm",sizeof(cdp_trans_t));
		return 0;
	}
	x->ptr = shm_malloc(sizeof(void*));
	if (!x->ptr) {
		LOG_NO_MEM("shm",sizeof(void*));
		shm_free(x);
		return 0;
	}
	x->endtoendid = msg->endtoendId;
	x->hopbyhopid = msg->hopbyhopId;
	x->cb = cb;
	*(x->ptr) = ptr;
	x->expires = timeout + time(0);
	x->auto_drop = auto_drop;
	x->next = 0;

	lock_get(trans_list->lock);
	x->prev = trans_list->tail;
	if (trans_list->tail) trans_list->tail->next = x;
	trans_list->tail = x;
	if (!trans_list->head) trans_list->head = x;
	lock_release(trans_list->lock);
	return x;
}
示例#4
0
/** Adds a new client to list of clients being serviced
@Params
int timeout - Interim period
int callID - je->cid used to identify the subscriber being processed
char *subscriber - subscriber name, e.g., Alice
int cherge_type - online or offline charging (1 or 0)
int did - SIP dialog ID
Returns - 0 on failure and 1 on success
*/
inline int add_client(int timeout, int callID, char *subscriber, int charge_type, int did)
{
	a_client *this;
	this = shm_malloc(sizeof(a_client));
	if (!this) {
		LOG_NO_MEM("shm",sizeof(a_client));
		return 0;
	}

	this->ptr = shm_malloc(sizeof(void*));
	if (!this->ptr) {
		LOG_NO_MEM("shm",sizeof(void*));
		shm_free(this);
		return 0;
	}	
	
	this->next = 0;
	this->call_id = callID;
	this->call_did = did;
	this->credits = 0;
	this->timeout = timeout;
	this->clocking = Not;
	this->subscriber = subscriber;
	this->charge_type = charge_type;
	this->onceoff_credit = 0;
	this->persec_credit = 0;
	this->perMbyte_credit = 0;
	this->used_crtdonce = 0;
	this->used_crtdpsec = 0;
	this->used_crtdpMb = 0;
	this->used_crtdonce_buf = 0;
	this->used_crtdpsec_buf = 0;
	this->used_crtdpMb_buf = 0;
	this->used_crtdonce_buf1 = 0;
	this->used_crtdpsec_buf1 = 0;
	this->used_crtdpMb_buf1 = 0;
		
	lock_get(list_of_clients->lock);
	this->prev = list_of_clients->tail;

	if(list_of_clients->tail){
		LOG(L_DBG,"add_client - Clients exist at tail\n");
		list_of_clients->tail->next =this;
	}
	list_of_clients->tail = this;
	
	if (!list_of_clients->head) {
		LOG(L_DBG,"add_client - No client at head means no clients in the list\n");
		list_of_clients->head = this;
	}
	lock_release(list_of_clients->lock);
	LOG(L_DBG,"add_client - We added client Name %s with callID %d\n",this->subscriber,this->call_id);
	
	return 1;
}
/**
 * Initializes the session related structures.
 */
int sessions_init(int hash_size)
{
	int i;
	session_lock = lock_alloc();
	if (!session_lock){
		LOG_NO_MEM("lock",sizeof(gen_lock_t));
		goto error;
	}
	session_lock = lock_init(session_lock);
	sessions_hash_size=hash_size;
	
	sessions = shm_malloc(sizeof(cdp_session_list_t)*hash_size);
	if (!sessions){
		LOG_NO_MEM("shm",sizeof(cdp_session_list_t)*hash_size);
		goto error;
	}
	memset(sessions,0,sizeof(cdp_session_list_t)*hash_size);
	
	for(i=0;i<hash_size;i++){
		sessions[i].lock = lock_alloc();
		if (!sessions[i].lock){
			LOG_NO_MEM("lock",sizeof(gen_lock_t));
			goto error;
		}
		sessions[i].lock = lock_init(sessions[i].lock);
	}
	
	session_id1 = shm_malloc(sizeof(unsigned int));
	if (!session_id1){
		LOG_NO_MEM("shm",sizeof(unsigned int));
		goto error;
	}
	session_id2 = shm_malloc(sizeof(unsigned int));
	if (!session_id2){
		LOG_NO_MEM("shm",sizeof(unsigned int));
		goto error;
	}
	srand((unsigned int)time(0));	
	*session_id1 = rand();
	*session_id1 <<= 16;
	*session_id1 += time(0)&0xFFFF;
	*session_id2 = 0;
	
	add_timer(1,0,session_timer,0);
	return 1;
error:
	return 0;
}
示例#6
0
/*
 * Initializes the charging timer
 @Params
 char *key_value_file - the IPTV hash table configuration file
 * 
 * */
int msg_timer_init(char *key_value_file)
{
	LOG(L_INFO,"UCT IMS Charging System\n");
	LOG(L_INFO,"Developers: Vitalis Gavole Ozianyi and Joyce B. Mwangama (2009)\n");
	LOG(L_INFO,"INFO: msg_timer_init() - Initialize message timer\n");
	list_of_clients = shm_malloc(sizeof(client_list));
	if (!list_of_clients){
		LOG_NO_MEM("shm",sizeof(client_list));
		return 0;
	}
	list_of_clients->head = 0;
	list_of_clients->tail = 0;
	list_of_clients->lock = lock_alloc();
	list_of_clients->lock = lock_init(list_of_clients->lock);

	if(!add_timer(1,0,&msg_timer,0))
	{
	LOG(L_ERR,"CTF - msg_timer_init() - Failed to adder timer");
	return 0;
	}
		
	LOG(L_INFO,"INFO: msg_timer_init() - Calling the IPTV function\n\n");
	
	if(!iptv_start(key_value_file))
	{
	LOG(L_CRIT,"CRITICAL: msg_timer_init() - Error on iptv_start\n");
	return 0;
	}
	
return 1;
}
示例#7
0
/**
 * Create a new peer.
 * - All the memory from parameters is duplicated.
 * @param fqdn - FQDN of the peer
 * @param realm - Realm of the peer
 * @param port - port of the peer to connect to
 * @returns the new peer* if ok, NULL on error
 */
peer* new_peer(str fqdn,str realm,int port)
{
	peer *x;
	x = shm_malloc(sizeof(peer));
	if (!x){
		LOG_NO_MEM("shm",sizeof(peer));
		goto error;
	}
	memset(x,0,sizeof(peer));
	shm_str_dup(x->fqdn,fqdn);
	if (!x->fqdn.s) goto error;	
	shm_str_dup(x->realm,realm);
	if (!x->realm.s) goto error;	
	x->port = port;
	x->lock = lock_alloc();
	x->lock = lock_init(x->lock);
		
	x->state = Closed;

	x->I_sock = -1;
	x->R_sock = -1;

	x->activity = time(0)-500;	
	
	x->next = 0;
	x->prev = 0;
	
	return x;
error:
	return 0;
}
示例#8
0
/**
 * Initializes the worker structures, like the task queue.
 */
void worker_init()
{
	tasks = shm_malloc(sizeof(task_queue_t));
	
	tasks->lock = lock_alloc();
	tasks->lock = lock_init(tasks->lock);
	
	tasks->empty = semget(IPC_PRIVATE,1,0666 | IPC_CREAT );
	if (tasks->empty==-1){
		LOG(L_ERR,"ERROR:worker_init(): Error creating semaphore for empty queue > %s\n",strerror(errno));
	}else
		semctl(tasks->empty, 0, SETVAL, cdp_semun_init );
	tasks->full = semget(IPC_PRIVATE,1, 0666 | IPC_CREAT );
	if (tasks->full==-1){
		LOG(L_ERR,"ERROR:worker_init(): Error creating semaphore for full queue > %s\n",strerror(errno));
	}else
		semctl(tasks->full, 0, SETVAL, cdp_semun_init);
	
	tasks->start = 0;
	tasks->end = 0;
	tasks->max = config->queue_length;
	tasks->queue = shm_malloc(tasks->max*sizeof(task_t));
	if (!tasks->queue) LOG_NO_MEM("shm",tasks->max*sizeof(task_t));
	memset(tasks->queue,0,tasks->max*sizeof(task_t));
		
	callbacks = shm_malloc(sizeof(cdp_cb_list_t));
	callbacks->head = 0; 
	callbacks->tail = 0;
	
	cdp_lock_get(tasks->empty);
//	lock_release(tasks->full);	
}
示例#9
0
/*unsafe*/
int cb_add(cdp_cb_f cb, void *ptr) {
    cdp_cb_t *x;
    x = shm_malloc(sizeof (cdp_cb_t));
    if (!x) {
        LOG_NO_MEM("shm", sizeof (cdp_cb_t));
        return 0;
    }
    x->cb = cb;
    x->ptr = shm_malloc(sizeof (void*));
    if (!x->ptr) {
        LOG_NO_MEM("shm", sizeof (void*));
        return 0;
    }
    *(x->ptr) = ptr;
    x->next = 0;
    x->prev = callbacks->tail;
    if (callbacks->tail) callbacks->tail->next = x;
    callbacks->tail = x;
    if (!callbacks->head) callbacks->head = x;
    return 1;
}
示例#10
0
文件: config.c 项目: 4N7HR4X/kamailio
/**
 * Create a new dp_config.
 */
inline routing_entry *new_routing_entry()
{
	routing_entry *x;
	x = shm_malloc(sizeof(routing_entry));
	if (!x) {
		LOG_NO_MEM("shm",sizeof(routing_entry));
		goto error;
	}
	memset(x,0,sizeof(routing_entry));
	return x;
error:
	LM_ERR("%s(): failed to create new routing_entry.\n",__FUNCTION__);
	return 0;
}
示例#11
0
文件: config.c 项目: 4N7HR4X/kamailio
/**
 * Create a new dp_config.
 */
inline dp_config *new_dp_config()
{
	dp_config *x;
	x = shm_malloc(sizeof(dp_config));
	if (!x) {
		LOG_NO_MEM("shm",sizeof(dp_config));
		goto error;
	}
	memset(x,0,sizeof(dp_config));
	return x;
error:
	LM_ERR("%s(): failed to create new dp_config.\n",__FUNCTION__);
	return 0;
}
示例#12
0
/**
 * Initializes the transaction structure.
 * Also adds a timer callback for checking the transaction statuses
 * @returns 1 if success or 0 on error
 */
int cdp_trans_init()
{
	trans_list = shm_malloc(sizeof(cdp_trans_list_t));
	if (!trans_list){
		LOG_NO_MEM("shm",sizeof(cdp_trans_list_t));
		return 0;
	}
	trans_list->head = 0;
	trans_list->tail = 0;
	trans_list->lock = lock_alloc();
	trans_list->lock = lock_init(trans_list->lock);

	add_timer(1,0,cdp_trans_timer,0);
	return 1;
}
示例#13
0
/* and in here we also loop for exosip events*/
void acceptor_process(dp_config *cfg)
{
	
	
	int i,k;
	unsigned int sock;
	
	LOG(L_INFO,"INFO:Acceptor process starting up...\n");
	
	listening_socks = pkg_malloc((cfg->acceptors_cnt+1)*sizeof(int));
	if (!listening_socks){
		LOG_NO_MEM("pkg",(cfg->acceptors_cnt+1)*sizeof(int));
		goto done;
	}
	memset(listening_socks,0,(cfg->acceptors_cnt+1)*sizeof(int));	
	k=0;
	for(i=0;i<cfg->acceptors_cnt;i++)
		if (create_socket(cfg->acceptors[i].port,cfg->acceptors[i].bind,&sock)){
			listening_socks[k++]=sock;			
		}	

	
	LOG(L_INFO,"INFO:... Acceptor opened sockets. Entering accept loop ...\n");		
	accept_loop();
	
	for(i=0;listening_socks[i];i++)
		close(listening_socks[i]);
	
	if (listening_socks) pkg_free(listening_socks);
#ifdef CDP_FOR_SER
#else
#ifdef PKG_MALLOC
	#ifdef PKG_MALLOC
		LOG(memlog, "Acceptor Memory status (pkg):\n");
		//pkg_status();
		#ifdef pkg_sums
			pkg_sums();
		#endif 
	#endif
#endif
		dp_del_pid(getpid());		
#endif		
done:		
	LOG(L_INFO,"INFO:... Acceptor process finished\n");
	exit(0);
}
示例#14
0
/**
 * Create a new session structure
 * @param id - the session id string, already allocated in shm
 * @param type - the session type
 * @returns the new cdp_session_t on success or 0 on failure
 */
cdp_session_t* new_session(str id,cdp_session_type_t type)
{
	cdp_session_t *x=0;

	x = shm_malloc(sizeof(cdp_session_t));
	if (!x){
		LOG_NO_MEM("shm",sizeof(cdp_session_t));
		goto error;
	}
	memset(x,0,sizeof(cdp_session_t));
	x->id = id;
	x->type = type;
	x->hash = get_str_hash(x->id,sessions_hash_size);
	return x;
error:
	return 0;
}
示例#15
0
/*
 * Initializes the timer for Listening to SIP requests at the IPTV server
 * */
int sip_timer_init()
{
	a_sip_lock = shm_malloc(sizeof(sip_lock));
	if(!a_sip_lock){
		LOG_NO_MEM("shm",sizeof(sip_lock));
		return 0;
	}
	
	a_sip_lock->lock = lock_alloc();
	a_sip_lock->lock = lock_init(a_sip_lock->lock);

	if(!add_timer(1,0,&sip_timer,0))
	{
	LOG(L_ERR,"CTF - sip_timer_init() - Failed to adder timer");
	return 0;
	}
	return 1;
}
/**
 * Trim the quotes from a string and duplicate it.
 * @param dest - destination for the untrimmed and duplicated string
 * @param src - source string
 */
static inline void quote_trim_dup(str *dest, char *src)
{
	int i=0;
	dest->s=0;
	dest->len=0;
	if (!src) return;
	dest->len = strlen(src);
	if (src[0]=='\"') {i++;dest->len--;}
	if (src[dest->len-1]=='\"') {dest->len--;}

	dest->s = shm_malloc(dest->len+1);
	if (!dest->s) {
		LOG_NO_MEM("shm",dest->len);
		dest->len=0;
		return;
	}
	memcpy(dest->s,src+i,dest->len);
	dest->s[dest->len]=0;
}
示例#17
0
/**
 * Add a pid to the local process list.
 * @param pid newly forked pid
 * @returns 1 on success or 0 on error
 */
inline int dp_add_pid(pid_t pid)
{
	pid_list_t *n;
	lock_get(pid_list_lock);
	n = shm_malloc(sizeof(pid_list_t));
	if (!n){
		LOG_NO_MEM("shm",sizeof(pid_list_t));
		lock_release(pid_list_lock);
		return 0;
	}
	n->pid = pid;
	n->next = 0;
	n->prev = pid_list->tail;
	if (!pid_list->head) pid_list->head = n;
	if (pid_list->tail) pid_list->tail->next = n;
	pid_list->tail = n;
	lock_release(pid_list_lock);
	return 1;
}
示例#18
0
/**
 * Initializes the worker structures, like the task queue.
 */
void worker_init()
{
	tasks = shm_malloc(sizeof(task_queue_t));
	
	tasks->lock = lock_alloc();
	tasks->lock = lock_init(tasks->lock);
	
	sem_new(tasks->empty,0);
		
	sem_new(tasks->full,1);
		
	tasks->start = 0;
	tasks->end = 0;
	tasks->max = config->queue_length;
	tasks->queue = shm_malloc(tasks->max*sizeof(task_t));
	if (!tasks->queue) {
		LOG_NO_MEM("shm",tasks->max*sizeof(task_t));
		goto out_of_memory;
	}
	memset(tasks->queue,0,tasks->max*sizeof(task_t));
		
	callbacks = shm_malloc(sizeof(cdp_cb_list_t));
	if (!callbacks) goto out_of_memory;
	callbacks->head = 0; 
	callbacks->tail = 0;
	return;
out_of_memory:
	if (tasks){
		if (tasks->lock) {
			lock_destroy(tasks->lock);
			lock_dealloc(&(tasks->lock)); 
		}
		sem_free(tasks->full);
		sem_free(tasks->empty);
		if (tasks->queue) shm_free(tasks->queue);
		shm_free(tasks);
	}
	if (callbacks) shm_free(callbacks);
}
示例#19
0
文件: receiver.c 项目: 2pac/kamailio
/**
 * Does the actual receive operations on the Diameter TCP socket, for retrieving incoming messages.
 * The functions is to be called iteratively, each time there is something to be read from the TCP socket. It uses
 * a simple state machine to read first the version, then the header and then the rest of the message. When an
 * entire message is received, it is decoded and passed to the processing functions.
 * @param sp - the serviced peer to operate on
 * @return 1 on success, 0 on failure
 */
static inline int do_receive(serviced_peer_t *sp)
{
	int cnt,n,version;
	char *dst;
	AAAMessage *dmsg;

	switch (sp->state){
		case Receiver_Waiting:
			n = 1; /* wait for version */
			dst = sp->buf;
			break;

		case Receiver_Header:
			n = DIAMETER_HEADER_LEN - sp->buf_len; /* waiting for rest of header */
			dst = sp->buf+sp->buf_len;
			break;

		case Receiver_Rest_of_Message:
			n = sp->length - sp->msg_len;	/* waiting for the rest of the message */
			dst = sp->msg+sp->msg_len;
			break;

		default:
			LM_ERR("do_receive(): [%.*s] Unknown state %d\n",
					sp->p?sp->p->fqdn.len:0,
					sp->p?sp->p->fqdn.s:0,
					sp->state);
			goto error_and_reset;
	}

	cnt = recv(sp->tcp_socket,dst,n,0);

	if (cnt<=0)
		goto error_and_reset;

	switch (sp->state){
		case Receiver_Waiting:
			version = (unsigned char)(sp->buf[0]);
			if (version!=1) {
		  		LM_ERR("do_receive(): [%.*s] Received Unknown version [%d]\n",
		  				sp->p->fqdn.len,
		  				sp->p->fqdn.s,
		  				(unsigned char)sp->buf[0]);
				goto error_and_reset;
			}else{
				sp->state = Receiver_Header;
				sp->buf_len = 1;
			}
			break;

		case Receiver_Header:
			sp->buf_len+=cnt;
			if (sp->buf_len==DIAMETER_HEADER_LEN){
				sp->length = get_3bytes(sp->buf+1);
				if (sp->length>DP_MAX_MSG_LENGTH){
					LM_ERR("do_receive(): [%.*s] Msg too big [%d] bytes\n",
							sp->p?sp->p->fqdn.len:0,
							sp->p?sp->p->fqdn.s:0,
							sp->length);
					goto error_and_reset;
				}
				LM_DBG("receive_loop(): [%.*s] Recv Version %d Length %d\n",
						sp->p?sp->p->fqdn.len:0,
						sp->p?sp->p->fqdn.s:0,
						(unsigned char)(sp->buf[0]),
						sp->length);
				sp->msg = shm_malloc(sp->length);
				if (!sp->msg) {
					LOG_NO_MEM("shm",sp->length);
					goto error_and_reset;
				}

				memcpy(sp->msg,sp->buf,sp->buf_len);
				sp->msg_len=sp->buf_len;
				sp->state = Receiver_Rest_of_Message;
			}
			break;

		case Receiver_Rest_of_Message:
			sp->msg_len+=cnt;
			if (sp->msg_len==sp->length){
		    	dmsg = AAATranslateMessage((unsigned char*)sp->msg,(unsigned int)sp->msg_len,1);
				if (dmsg) {
					sp->msg = 0;
					receive_message(dmsg,sp);
				}
				else {
					shm_free(sp->msg);
					sp->msg = 0;
				}
				sp->msg_len = 0;
				sp->buf_len = 0;
				sp->state = Receiver_Waiting;
			}
			break;

		default:
			LM_ERR("do_receive(): [%.*s] Unknown state %d\n",
					sp->p?sp->p->fqdn.len:0,
					sp->p?sp->p->fqdn.s:0,
					sp->state);
			goto error_and_reset;
	}
	return 1;
error_and_reset:
	if (sp->msg){
		shm_free(sp->msg);
		sp->msg = 0;
		sp->msg_len = 0;
		sp->buf_len = 0;
		sp->state = Receiver_Waiting;
	}
	return 0;
}
示例#20
0
/**
 * Initialize the CDiameterPeer from a configuration file.
 * The file is kept as dtd. See configdtd.h for the DTD and ConfigExample.xml.
 * @param cfg_filename - file with the configuration
 * @returns 1 on success, 0 on error
 */
int diameter_peer_init(char *cfg_filename)
{	
	pid_list_t *i,*j;

	config = parse_dp_config(cfg_filename);
	if (!config) {
		LOG(L_ERR,"ERROR:init_diameter_peer(): Error loading configuration file. Aborting...\n");
		goto error;
	}
	log_dp_config(L_INFO,config);
	
	dp_first_pid = shm_malloc(sizeof(pid_t));
	if (!dp_first_pid){
		LOG_NO_MEM("shm",sizeof(pid_t));
		goto error;
	}
	*dp_first_pid = getpid();
	
	shutdownx = shm_malloc(sizeof(int));
	if (!shutdownx){
		LOG_NO_MEM("shm",sizeof(int));
		goto error;
	}
	*shutdownx = 0;
	
	shutdownx_lock = lock_alloc();
	if (!shutdownx_lock){
		LOG_NO_MEM("shm",sizeof(gen_lock_t));
		goto error;
	}
	shutdownx_lock = lock_init(shutdownx_lock);

	handlers_lock = lock_alloc();
	if (!handlers_lock){
		LOG_NO_MEM("shm",sizeof(gen_lock_t));
		goto error;
	}
	handlers_lock = lock_init(handlers_lock);

	handlers = shm_malloc(sizeof(handler_list));
	if (!handlers){
		LOG_NO_MEM("shm",sizeof(handler_list));
		goto error;
	}
	handlers->head=0;
	handlers->tail=0;

	/* init the pid list */
	pid_list = shm_malloc(sizeof(pid_list_head_t));
	pid_list_lock = lock_alloc();
	pid_list_lock = lock_init(pid_list_lock);

	/* init shared mem pointers before forking */
	timer_cdp_init();
	worker_init();

	/* init the peer manager */
	peer_manager_init(config);
	
	/* init the msg_handler */
	//msg_timer_init();
	
	/* init the session */
	if (!session_init()) goto error;
	
#ifdef CDP_FOR_SER
	/* init diameter transactions */
	trans_init();
	
	/* add callback for messages - used to implement the API */
	cb_add(api_callback,0);
		
#endif

/***********
Added by Vitalis to initialize the transactions

**********/
	/* init diameter transactions */
	trans_init();
	
	/* add callback for messages - used to implement the API */
	cb_add(api_callback,0);

/*******End of addition ***********/

	
	return 1;
	
error:
	if (shutdownx) shm_free(shutdownx);
	if (config) free_dp_config(config);
	i = pid_list->head;
	while(i){
		j = i->next;
		shm_free(i);
		i = j;
	}
	shm_free(pid_list);
	lock_get(pid_list_lock);
	lock_destroy(pid_list_lock);
	lock_dealloc((void*)pid_list_lock);
	return 0;	

}
/**
 * Parses a DiameterPeer configuration file.
 * @param filename - path to the file
 * @returns the dp_config* structure containing the parsed configuration  
 */
dp_config* parse_dp_config(xmlDocPtr doc)
{
	dp_config *x=0;
	xmlNodePtr root=0,child=0,nephew=0;
	xmlChar *xc=0;
	int k;
	routing_entry *re,*rei;
	routing_realm *rr,*rri;
	
	if (!doc)
		goto error;
		
	x = new_dp_config();

	root = xmlDocGetRootElement(doc);
	if (!root){
		LOG(L_ERR,"ERR:parse_dp_config():  Empty XML \n");
		goto error;
	}

	k = xmlStrlen(root->name);
	if (k>12) k = 12;
	if (strncasecmp((char*)root->name,"DiameterPeer",k)!=0){
		LOG(L_ERR,"ERR:parse_dp_config(): XML Root is not <DiameterPeer>\n");
		goto error;
	}

	xc = xmlGetProp(root,(xmlChar*)"FQDN");
	if (xc){
		quote_trim_dup(&(x->fqdn),(char*)xc);
		quote_trim_dup(&(x->identity),(char*)xc);
		xmlFree(xc);
	}
	
	xc = xmlGetProp(root,(xmlChar*)"Realm");
	if (xc){
		quote_trim_dup(&(x->realm),(char*)xc);
		xmlFree(xc);
	}
	
	xc = xmlGetProp(root,(xmlChar*)"Vendor_Id");
	if (xc) x->vendor_id = atoi((char*)xc);
	else x->vendor_id = 0;

	xc = xmlGetProp(root,(xmlChar*)"Product_Name");
	if (xc){
		quote_trim_dup(&(x->product_name),(char*)xc);
		xmlFree(xc);
	}
	
	xc = xmlGetProp(root,(xmlChar*)"AcceptUnknownPeers");
	if (xc) {x->accept_unknown_peers = atoi((char*)xc);xmlFree(xc);}
	else x->accept_unknown_peers = 1;
	
	xc = xmlGetProp(root,(xmlChar*)"DropUnknownOnDisconnect");
	if (xc) {x->drop_unknown_peers = atoi((char*)xc);xmlFree(xc);}
	else x->drop_unknown_peers = 1;
	
	xc = xmlGetProp(root,(xmlChar*)"Tc");
	if (xc) {x->tc = atoi((char*)xc);xmlFree(xc);}
	else x->tc = 30;

	xc = xmlGetProp(root,(xmlChar*)"Workers");
	if (xc) {x->workers = atoi((char*)xc);xmlFree(xc);}
	else x->workers = 4;

	xc = xmlGetProp(root,(xmlChar*)"QueueLength");
	if (xc) {x->queue_length = atoi((char*)xc);xmlFree(xc);}
	else x->queue_length = 32;

	xc = xmlGetProp(root,(xmlChar*)"TransactionTimeout");
	if (xc) {x->transaction_timeout = atoi((char*)xc);xmlFree(xc);}
	else x->transaction_timeout = 5;
	
	xc = xmlGetProp(root,(xmlChar*)"SessionsHashSize");
	if (xc) {x->sessions_hash_size = atoi((char*)xc);xmlFree(xc);}
	else x->sessions_hash_size = 128;
	
	for(child = root->children; child; child = child->next)
		if (child->type == XML_ELEMENT_NODE)
	{
		if (xmlStrlen(child->name)==4 && strncasecmp((char*)child->name,"Peer",4)==0){
			//PEER
			x->peers_cnt++;		
		}
		else if (xmlStrlen(child->name)==8 && strncasecmp((char*)child->name,"Acceptor",8)==0){
			//Acceptor
			x->acceptors_cnt++;		
		}
		else if (xmlStrlen(child->name)==4 && (strncasecmp((char*)child->name,"Auth",4)==0||
			strncasecmp((char*)child->name,"Acct",4)==0)){
			//Application
			x->applications_cnt++;		
		}	
	}
	x->peers = shm_malloc(x->peers_cnt*sizeof(peer_config));
	if (!x->peers){
		LOG_NO_MEM("shm",x->peers_cnt*sizeof(peer_config));
		goto error;
	}
	memset(x->peers,0,x->peers_cnt*sizeof(peer_config));
	x->peers_cnt=0;
	x->acceptors = shm_malloc(x->acceptors_cnt*sizeof(acceptor_config));
	if (!x->acceptors){
		LOG_NO_MEM("shm",x->acceptors_cnt*sizeof(acceptor_config));
		goto error;
	}
	memset(x->acceptors,0,x->acceptors_cnt*sizeof(acceptor_config));
	x->acceptors_cnt=0;
	x->applications = shm_malloc(x->applications_cnt*sizeof(app_config));
	if (!x->applications){
		LOG_NO_MEM("shm",x->applications_cnt*sizeof(app_config));
		goto error;
	}
	memset(x->applications,0,x->applications_cnt*sizeof(app_config));
	x->applications_cnt=0;

	for(child = root->children; child; child = child->next)
		if (child->type == XML_ELEMENT_NODE)
	{
		if (xmlStrlen(child->name)==4 && strncasecmp((char*)child->name,"Peer",4)==0){
			//PEER
			xc = xmlGetProp(child,(xmlChar*)"FQDN");
			if (xc){
				quote_trim_dup(&(x->peers[x->peers_cnt].fqdn),(char*)xc);
				xmlFree(xc);
			}
			xc = xmlGetProp(child,(xmlChar*)"Realm");
			if (xc){
				quote_trim_dup(&(x->peers[x->peers_cnt].realm),(char*)xc);			
				xmlFree(xc);
			}
			xc = xmlGetProp(child,(xmlChar*)"port");
			if (xc){
				x->peers[x->peers_cnt].port = atoi((char*)xc);
				xmlFree(xc);
			}
			x->peers_cnt++;		
		}
		else if (xmlStrlen(child->name)==8 && strncasecmp((char*)child->name,"Acceptor",8)==0){
			//Acceptor
			xc = xmlGetProp(child,(xmlChar*)"bind");			
			if (xc){
				quote_trim_dup(&(x->acceptors[x->acceptors_cnt].bind),(char*)xc);			
				xmlFree(xc);
			}
			xc = xmlGetProp(child,(xmlChar*)"port");
			if (xc){
				x->acceptors[x->acceptors_cnt].port = atoi((char*)xc);						
				xmlFree(xc);
			}
			x->acceptors_cnt++;		
		}
		else if (xmlStrlen(child->name)==4 && ((char*)strncasecmp((char*)child->name,"Auth",4)==0||
			strncasecmp((char*)child->name,"Acct",4)==0)){
			//Application
			xc = xmlGetProp(child,(xmlChar*)"id");	
			if (xc){
				x->applications[x->applications_cnt].id = atoi((char*)xc);						
				xmlFree(xc);
			}
			xc = xmlGetProp(child,(xmlChar*)"vendor");
			if (xc){
				x->applications[x->applications_cnt].vendor = atoi((char*)xc);						
				xmlFree(xc);
			}
			if (child->name[1]=='u'||child->name[1]=='U')
				x->applications[x->applications_cnt].type = DP_AUTHORIZATION;						
			else
				x->applications[x->applications_cnt].type = DP_ACCOUNTING;										
			x->applications_cnt++;		
		}	
		else if (xmlStrlen(child->name)==12 && ((char*)strncasecmp((char*)child->name,"DefaultRoute",12)==0)){
			if (!x->r_table) {
				x->r_table = shm_malloc(sizeof(routing_table));
				memset(x->r_table,0,sizeof(routing_table));
			}
			re = new_routing_entry();
			if (re){			
				xc = xmlGetProp(child,(xmlChar*)"FQDN");
				if (xc){
					quote_trim_dup(&(re->fqdn),(char*)xc);			
					xmlFree(xc);
				}
				xc = xmlGetProp(child,(xmlChar*)"metric");			
				if (xc){
					re->metric = atoi((char*)xc);			
					xmlFree(xc);
				}
				
				/* add it the list in ascending order */
				if (! x->r_table->routes || re->metric <= x->r_table->routes->metric){
					re->next = x->r_table->routes;
					x->r_table->routes = re;
				}else{
					for(rei=x->r_table->routes;rei;rei=rei->next)
						if (!rei->next){
							rei->next = re;
							break;						
						}else{
							if (re->metric <= rei->next->metric){
								re->next = rei->next;
								rei->next = re;
								break;
							}
						}				
				}
			}					
		}
		else if (xmlStrlen(child->name)==5 && ((char*)strncasecmp((char*)child->name,"Realm",5)==0)){
			if (!x->r_table) {
				x->r_table = shm_malloc(sizeof(routing_table));
				memset(x->r_table,0,sizeof(routing_table));
			}
			rr = new_routing_realm();
			if (rr){			
				xc = xmlGetProp(child,(xmlChar*)"name");
				quote_trim_dup(&(rr->realm),(char*)xc);			
				
				if (!x->r_table->realms) {				
					x->r_table->realms = rr;
				}else{				
					for(rri=x->r_table->realms;rri->next;rri=rri->next);
					rri->next = rr;				
				}			
				for(nephew = child->children; nephew; nephew = nephew->next)
					if (nephew->type == XML_ELEMENT_NODE){
						if (xmlStrlen(nephew->name)==5 && ((char*)strncasecmp((char*)nephew->name,"Route",5)==0))
						{
							re = new_routing_entry();
							if (re) {
								xc = xmlGetProp(nephew,(xmlChar*)"FQDN");
								if (xc){
									quote_trim_dup(&(re->fqdn),(char*)xc);	
									xmlFree(xc);
								}
								xc = xmlGetProp(nephew,(xmlChar*)"metric");
								if (xc){
									re->metric = atoi((char*)xc);			
									xmlFree(xc);
								}
								/* add it the list in ascending order */
								if (! rr->routes || re->metric <= rr->routes->metric){
									re->next = rr->routes;
									rr->routes = re;
								}else{
									for(rei=rr->routes;rei;rei=rei->next)
										if (!rei->next){
											rei->next = re;
											break;						
										}else{
											if (re->metric <= rei->next->metric){
												re->next = rei->next;
												rei->next = re;
												break;
											}
										} 					
								}
							}
						}
					}
			}		
		}
	}
	
	if (doc) xmlFreeDoc(doc);	
	parser_destroy();
	return x;
error:
	if (doc) xmlFreeDoc(doc);
	parser_destroy();
	if (x) free_dp_config(x);
	return 0;	
}
示例#22
0
文件: receiver.c 项目: asyn/openvims
/** 
 * Receive Loop for Diameter messages.
 * Decodes the message and calls receive_message().
 * @param sock - the socket to receive from
 * @returns when the socket is closed
 */
void receive_loop(int sock)
{
	char buf[hdr_len],*msg;
	int buf_len,length,version,cnt,msg_len;
	AAAMessage *dmsg;
	
    while(!*shutdownx){
   		buf_len=0;
    	while(buf_len<1){	
    		cnt = select_recv(sock,buf+buf_len,1,0);
	    	if (cnt<0) goto error;
	    	buf_len+=cnt;
    	}
    	version = (unsigned char)buf[0];
    	if (version!=1) {
    		LOG(L_ERR,"ERROR:receive_loop():[%d] Recv Unknown version [%d]\n",sock,(unsigned char)buf[0]);
			continue;    		
    	}    	
    	while(buf_len<hdr_len){
	    	cnt = select_recv(sock,buf+buf_len,hdr_len-buf_len,0);
	    	if (cnt<0) goto error;
	    	buf_len+=cnt;
    	}
    	length = get_3bytes(buf+1);
    	if (length>DP_MAX_MSG_LENGTH){
			LOG(L_ERR,"ERROR:receive_loop():[%d] Msg too big [%d] bytes\n",sock,length);
			goto error;
    	}
    	LOG(L_DBG,"DBG:receive_loop():[%d] Recv Version %d Length %d\n",sock,version,length);
    	msg = shm_malloc(length);
    	if (!msg) {
    		LOG_NO_MEM("shm",length);
			goto error;
    	}
    		
    	memcpy(msg,buf,hdr_len);
    	msg_len=hdr_len;
    	while(msg_len<length){
    		cnt = select_recv(sock,msg+msg_len,length-msg_len,0);
	    	if (cnt<0) {
	    		shm_free(msg);
		    	goto error;
	    	}
    		msg_len+=cnt;
    	}
    	LOG(L_DBG,"DBG:receive_loop():[%d] Recv message complete\n",sock);
    	
    	dmsg = AAATranslateMessage((unsigned char*)msg,(unsigned int)msg_len,1);
    	
    	/*shm_free(msg);*/

		if (dmsg) receive_message(dmsg,sock);
		else{
			shm_free(msg);
		}
		
    }
error:
	if (this_peer) {
		if (this_peer->I_sock == sock) sm_process(this_peer,I_Peer_Disc,0,0,sock);
		if (this_peer->R_sock == sock) sm_process(this_peer,R_Peer_Disc,0,0,sock);
	}
    LOG(L_ERR,"INFO:receive_loop():[%d] Client closed connection or error... BYE\n",sock);
}
示例#23
0
/**
 * Real initialization, called after the config is parsed
 */
int diameter_peer_init_real()
{
	pid_list_t *i,*j;

	if (!config) {
		LM_ERR("diameter_peer_init_real(): Configuration was not parsed yet. Aborting...\n");
		goto error;
	}
	log_dp_config(config);

	dp_first_pid = shm_malloc(sizeof(pid_t));
	if (!dp_first_pid){
		LOG_NO_MEM("shm",sizeof(pid_t));
		goto error;
	}
	*dp_first_pid = getpid();

	shutdownx = shm_malloc(sizeof(int));
	if (!shutdownx){
		LOG_NO_MEM("shm",sizeof(int));
		goto error;
	}
	*shutdownx = 0;

	shutdownx_lock = lock_alloc();
	if (!shutdownx_lock){
		LOG_NO_MEM("shm",sizeof(gen_lock_t));
		goto error;
	}
	shutdownx_lock = lock_init(shutdownx_lock);

	handlers_lock = lock_alloc();
	if (!handlers_lock){
		LOG_NO_MEM("shm",sizeof(gen_lock_t));
		goto error;
	}
	handlers_lock = lock_init(handlers_lock);

	handlers = shm_malloc(sizeof(handler_list));
	if (!handlers){
		LOG_NO_MEM("shm",sizeof(handler_list));
		goto error;
	}
	handlers->head=0;
	handlers->tail=0;

	/* init the pid list */
	pid_list = shm_malloc(sizeof(pid_list_head_t));
	if (!pid_list){
		LOG_NO_MEM("shm",sizeof(pid_list_head_t));
		goto error;
	}
	bzero(pid_list,sizeof(pid_list_head_t));
	pid_list_lock = lock_alloc();
	pid_list_lock = lock_init(pid_list_lock);

	/* init shared mem pointers before forking */
	timer_cdp_init();
	worker_init();

	/* init the peer manager */
	peer_manager_init(config);

	/* init diameter transactions */
	cdp_trans_init();

	/* init the session */
	if (!cdp_sessions_init(config->sessions_hash_size)) goto error;


	/* add callback for messages - used to implement the API */
	cb_add(api_callback,0);

	return 1;

error:
	if (shutdownx) shm_free(shutdownx);
	if (config) free_dp_config(config);
	i = pid_list->head;
	while(i){
		j = i->next;
		shm_free(i);
		i = j;
	}
	shm_free(pid_list);
	lock_get(pid_list_lock);
	lock_destroy(pid_list_lock);
	lock_dealloc((void*)pid_list_lock);
	return 0;

}