Exemplo n.º 1
0
/**
 * Shutdown the CDiameterPeer nicely.
 * It stops the workers, disconnects peers, drops timers and wait for all processes to exit.
 */
void diameter_peer_destroy()
{
	int pid,status;
	handler *h;

	lock_get(shutdownx_lock);
	if (*shutdownx) {
		/* already other process is cleaning stuff */
		lock_release(shutdownx_lock);
		return;
	}else {
		/* indicating that we are shuting down */
		*shutdownx = 1;
		lock_release(shutdownx_lock);
	}

	/* wait for all children to clean up nicely (acceptor, receiver, timer, workers) */
	LM_INFO("destroy_diameter_peer(): Terminating all children...\n");
	while(pid_list->tail){
		pid = dp_last_pid();
		if (pid<=0||pid==getpid()){
			dp_del_pid(pid);
			continue;
		}
		LM_INFO("destroy_diameter_peer(): Waiting for child [%d] to terminate...\n",pid);
		if (waitpid(pid,&status,0)<0){
			dp_del_pid(pid);
			continue;
		}
		if (!WIFEXITED(status) /*|| WIFSIGNALED(status)*/){
			sleep(1);
		} else {
			dp_del_pid(pid);
		}

	}
	LM_INFO("destroy_diameter_peer(): All processes terminated. Cleaning up.\n");

	/* clean upt the timer */
	timer_cdp_destroy();

	/* cleaning up workers */
	worker_destroy();

	/* cleaning peer_manager */
	peer_manager_destroy();

	/* cleaning up sessions */
	cdp_sessions_destroy();

	/* cleaning up transactions */
	cdp_trans_destroy();

	/* cleaning up global vars */
/*	lock_get(pid_list_lock);*/
	shm_free(dp_first_pid);
	shm_free(pid_list);
	lock_destroy(pid_list_lock);
	lock_dealloc((void*)pid_list_lock);

	shm_free(shutdownx);

	lock_destroy(shutdownx_lock);
	lock_dealloc((void*)shutdownx_lock);

	lock_get(handlers_lock);
	while(handlers->head){
		h = handlers->head->next;
		shm_free(handlers->head);
		handlers->head = h;
	}
	lock_destroy(handlers_lock);
	lock_dealloc((void*)handlers_lock);
	shm_free(handlers);

	free_dp_config(config);
	LM_CRIT("destroy_diameter_peer(): Bye Bye from C Diameter Peer test\n");

}
Exemplo n.º 2
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;

}
Exemplo n.º 3
0
/**
 * Shutdown the CDiameterPeer nicely.
 * It stops the workers, disconnects peers, drops timers and wait for all processes to exit.
 */
void diameter_peer_destroy()
{
	int pid,status;
	handler *h;
	
	lock_get(shutdownx_lock);
	if (*shutdownx) {
		/* already other process is cleaning stuff */
		lock_release(shutdownx_lock);			
		return;
	}else {
		/* indicating that we are shuting down */
		*shutdownx = 1;
		lock_release(shutdownx_lock);
	}


	worker_poison_queue();

	/* wait for all childs to clean up nicely (acceptor, receiver, timer, workers) */
	LOG(L_INFO,"INFO:destroy_diameter_peer(): Terminating all childs...\n");
	while(pid_list->tail){
		pid = dp_last_pid();
		if (pid<=0||pid==getpid()){
			dp_del_pid(pid);
			continue;
		}
		LOG(L_INFO,"INFO:destroy_diameter_peer(): Waiting for child [%d] to terminate...\n",pid);
		if (waitpid(pid,&status,0)<0){
			dp_del_pid(pid);
			continue;
		}
		if (!WIFEXITED(status) /*|| WIFSIGNALED(status)*/){
			worker_poison_queue();
			sleep(1);			
		} else {
			dp_del_pid(pid);
		}

	}
	LOG(L_INFO,"INFO:destroy_diameter_peer(): All processes terminated. Cleaning up.\n");
	
	/* clean upt the timer */
	timer_cdp_destroy();
	
	/* cleaning up workers */
	worker_destroy();
	
	/* cleaning peer_manager */
	peer_manager_destroy();
	
	/* cleaning up sessions */
	session_destroy();

	/* cleaning up global vars */
/*	lock_get(pid_list_lock);*/
	shm_free(dp_first_pid);
	shm_free(pid_list);
	lock_destroy(pid_list_lock);
	lock_dealloc((void*)pid_list_lock);
	
	shm_free(shutdownx);
	
	lock_destroy(shutdownx_lock);
	lock_dealloc((void*)shutdownx_lock);
	
	lock_get(handlers_lock);
	while(handlers->head){
		h = handlers->head->next;
		shm_free(handlers->head);
		handlers->head = h;
	}
	lock_destroy(handlers_lock);
	lock_dealloc((void*)handlers_lock);
	shm_free(handlers);
		
	free_dp_config(config);	
	LOG(L_CRIT,"INFO:destroy_diameter_peer(): Bye Bye from C Diameter Peer test\n");

#ifndef CDP_FOR_SER
	#ifdef PKG_MALLOC
		LOG(memlog, "Memory status (pkg):\n");
		//pkg_status();
		#ifdef pkg_sums
			pkg_sums();
		#endif 
	#endif
	#ifdef SHM_MEM
		LOG(memlog, "Memory status (shm):\n");
		//shm_status();
		#ifdef shm_sums
			shm_sums();
		#endif 
		/* zero all shmem alloc vars that we still use */
		shm_mem_destroy();
	#endif
#endif	
}
/**
 * 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;	
}
Exemplo n.º 5
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;	

}