Esempio n. 1
0
// Copies Logical Page from fromlp to tolp.
int
lp_copy (struct lpage *fromlp, struct lpage **tolp)
{

	struct lpage *newlp = NULL;
	paddr_t frompa; paddr_t topa;
	off_t swapaddr;
	int result;

	DEBUG(DB_VM, "LPage: lp_copy\n");

	lock_acquire(fromlp -> lock);

	frompa = fromlp -> paddr & PAGE_FRAME;
	if (frompa == INVALID_PADDR) {

		swapaddr = fromlp -> swapaddr;
		lock_release(fromlp -> lock);

		frompa = cm_allocuserpage(fromlp);
		if (frompa == INVALID_PADDR) {
			return (ENOMEM);
		}

		KASSERT(cm_pageispinned(frompa));

		lock_acquire(paging_lock);
		swap_pagein(frompa, swapaddr);
		lock_acquire(fromlp -> lock);
		lock_release(paging_lock);

		KASSERT((fromlp -> paddr & PAGE_FRAME) == INVALID_PADDR);

		fromlp -> paddr = frompa | LPF_LOCKED;

	}
	else {
		cm_pin(frompa);
	}

	KASSERT(cm_pageispinned(frompa));

	result = lp_setup(&newlp, &topa);
	if (result) {
		cm_unpin(frompa);
		lock_release(fromlp -> lock);
		return (result);
	}

	KASSERT(cm_pageispinned(topa));
	KASSERT(cm_pageispinned(frompa));
	cm_copypage(frompa, topa);
	cm_unpin(topa);
	cm_unpin(frompa);

	lock_release(fromlp -> lock);
	lock_release(newlp -> lock);

	*tolp = newlp;
	return (0);

}
Esempio n. 2
0
static struct mi_root* mi_cc_list_agents(struct mi_root *cmd_tree, void *param)
{
	struct cc_agent *agent;
	struct mi_root *rpl_tree;
	struct mi_node *node;
	struct mi_node *rpl;
	struct mi_attr *attr;
	str state;
	static str s_free={"free", 4};
	static str s_wrapup={"wrapup", 6};
	static str s_incall={"incall", 6};
	char *p;
	int len;
	int i;

	rpl_tree = init_mi_tree( 200, MI_SSTR("OK") );
	if ( rpl_tree==NULL)
		return NULL;
	rpl = &rpl_tree->node;
	rpl->flags |= MI_IS_ARRAY;

	/* block access to data */
	lock_get( data->lock );

	for(i=0; i< 2; i++) {
		for( agent=data->agents[i] ; agent ; agent=agent->next ) {
			node = add_mi_node_child( rpl, MI_DUP_VALUE, "Agent", 5,
					agent->id.s, agent->id.len );
			if (node==NULL)
					goto error;

			p = int2str( (unsigned long)(agent->ref_cnt), &len);
			attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ref"), p, len);
			if (attr==NULL)
					goto error;

			if(!agent->loged_in)
				attr = add_mi_attr( node, MI_DUP_VALUE, "Loged in", 8, "NO", 2);
			else {
				attr = add_mi_attr( node, MI_DUP_VALUE, "Loged in", 8, "YES", 3);
				if (attr==NULL)
					goto error;
				
				switch ( agent->state ) {
					case CC_AGENT_FREE:   state = s_free;   break;
					case CC_AGENT_WRAPUP: state = s_wrapup; break;
					case CC_AGENT_INCALL: state = s_incall; break;
					default: state.s =0;  state.len = 0;
				}
				attr = add_mi_attr( node, MI_DUP_VALUE, "State", 5,
						state.s, state.len );
			
			}
			if (attr==NULL)
					goto error;
		}
	}
	lock_release( data->lock );

	return rpl_tree;

error:
	lock_release( data->lock );
	return 0;
}
Esempio n. 3
0
static struct mi_root* mi_cc_list_queue(struct mi_root *cmd_tree, void *param)
{
	struct mi_root *rpl_tree;
	struct mi_node *node;
	struct mi_attr *attr;
	struct mi_node *rpl;
	struct cc_call *call;
	unsigned int n, now;
	char *p;
	int len;
	str *s;

	rpl_tree = init_mi_tree( 200, MI_SSTR("OK") );
	if ( rpl_tree==NULL)
		return NULL;
	rpl = &rpl_tree->node;
	rpl->flags |= MI_IS_ARRAY;

	n = 0;
	now = get_ticks();

	/* block access to data */
	lock_get( data->lock );

	for ( call=data->queue.first ; call ; call=call->lower_in_queue, n++) {

		p = int2str( (unsigned long)n, &len);
		node = add_mi_node_child( rpl, MI_DUP_VALUE, "Call", 4, p, len);
		if (node==NULL)
				goto error;

		p = int2str( (unsigned long)(now-call->last_start), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, "Waiting for", 11, p, len);
		if (attr==NULL)
				goto error;

		p = int2str( (unsigned long)(call->eta), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, "ETW", 3, p, len);
		if (attr==NULL)
				goto error;

		/* flow data */
		node = add_mi_node_child( node, MI_DUP_VALUE, "Flow", 4,
				call->flow->id.s, call->flow->id.len);
		if (node==NULL)
				goto error;

		p = int2str( (unsigned long)(call->flow->priority), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, "Priority", 8, p, len);
		if (attr==NULL)
				goto error;

		s = get_skill_by_id(data,call->flow->skill);
		if (s) {
			attr = add_mi_attr( node, MI_DUP_VALUE, "Skill", 5, s->s, s->len);
			if (attr==NULL)
					goto error;
		}
	}

	/* release the readers */
	lock_release( data->lock );

	return rpl_tree;
error:
	lock_release( data->lock );
	free_mi_tree(rpl_tree);
	return NULL;
}
Esempio n. 4
0
dbt_cache_p dbt_cache_get_db(str *_s)
{
	dbt_cache_p _dcache=NULL;;
	if(!_dbt_cachesem || !_dbt_cachedb)
	{
		LM_ERR("dbtext cache is not initialized! Check if you loaded"
				" dbtext before any other module that uses it\n");
		return NULL;
	}
	if(!_s || !_s->s || _s->len<=0)
		return NULL;

	LM_DBG("looking for db %.*s!\n",_s->len,_s->s);

	lock_get(_dbt_cachesem);
	
	_dcache = *_dbt_cachedb;
	while(_dcache)
	{
		if(_dcache->name.len==_s->len 
				&& !strncasecmp(_dcache->name.s, _s->s, _s->len))
		{
			LM_DBG("db already cached!\n");
			goto done;
		}
		
		_dcache = _dcache->next;
	}
	if(!dbt_is_database(_s))
	{
		LM_ERR("database [%.*s] does not exists!\n", _s->len, _s->s);
		goto done;
	}
	LM_DBG("new db!\n");
	
	_dcache = (dbt_cache_p)shm_malloc(sizeof(dbt_cache_t));
	if(!_dcache)
	{
		LM_ERR(" no shm memory for dbt_cache_t.\n");
		goto done;
	}
	memset(_dcache, 0, sizeof(dbt_cache_t));
	
	_dcache->name.s = (char*)shm_malloc((_s->len+1)*sizeof(char));
	if(!_dcache->name.s)
	{
		LM_ERR(" no shm memory for s!!\n");
		shm_free(_dcache);
		_dcache = NULL;
		goto done;
	}
	
	memcpy(_dcache->name.s, _s->s, _s->len);
	_dcache->name.s[_s->len] = '\0';
	_dcache->name.len = _s->len;
	
	if(*_dbt_cachedb)
		_dcache->next = *_dbt_cachedb;

	*_dbt_cachedb = _dcache;

done:
	lock_release(_dbt_cachesem);
	return _dcache;
}
Esempio n. 5
0
void store_b2b_dlg(b2b_table htable, unsigned int hsize, int type, int no_lock)
{
	int i;
	dlg_leg_t* leg;
	b2b_dlg_t* dlg;

	if (!b2be_dbf.init)
		return;

	qvals[0].val.int_val = type;
	//LM_DBG("storing b2b_entities type '%d' in db\n", type);
	if(b2be_dbf.use_table(b2be_db, &b2be_dbtable)< 0)
	{
		LM_ERR("sql use table failed\n");
		return;
	}

	for(i = 0; i< hsize; i++)
	{
		if(!no_lock)
			lock_get(&htable[i].lock);
		dlg = htable[i].first;
		while(dlg)
		{
			if(dlg->state < B2B_CONFIRMED || dlg->db_flag == NO_UPDATEDB_FLAG)
			{
				dlg = dlg->next;
				continue;
			}
			qvals[1].val.str_val     = dlg->tag[0];
			qvals[2].val.str_val     = dlg->tag[1];
			qvals[3].val.str_val     = dlg->callid;
			if(dlg->db_flag == INSERTDB_FLAG )
			{
				qvals[4].val.str_val = dlg->ruri;
				qvals[5].val.str_val = dlg->from_uri;
				qvals[6].val.str_val = dlg->from_dname;
				qvals[7].val.str_val = dlg->to_uri;
				qvals[8].val.str_val = dlg->to_dname;
				qvals[9].val.str_val = dlg->route_set[0];
				qvals[10].val.str_val= dlg->route_set[1];
				if(dlg->send_sock)
					qvals[11].val.str_val= dlg->send_sock->sock_str;
				else
				{
					qvals[11].val.str_val.s = 0;
					qvals[11].val.str_val.len = 0;
				}
				qvals[12].val.str_val= dlg->param;
			}

			qvals[13].val.int_val = dlg->state;
			qvals[14].val.int_val = dlg->cseq[0];
			qvals[15].val.int_val = dlg->cseq[1];
			qvals[16].val.int_val = dlg->last_method;
			qvals[17].val.int_val = dlg->last_reply_code;
			qvals[18].val.int_val = dlg->last_invite_cseq;
			qvals[19].val.str_val = dlg->contact[0];
			qvals[20].val.str_val = dlg->contact[1];

			leg = dlg->legs;
			if(leg) /* there can only be one leg as we do not deal with dialogs in early state */
			{
				qvals[21].val.str_val= leg->tag;
				qvals[22].val.int_val= leg->cseq;
				qvals[23].val.str_val= leg->contact;
				qvals[24].val.str_val= leg->route_set;
			}

			if(dlg->db_flag == INSERTDB_FLAG)
			{
				/* insert into database */
				if(b2be_dbf.insert(b2be_db, qcols, qvals, DB_COLS_NO)< 0)
				{
					LM_ERR("Sql insert failed\n");
					if(!no_lock)
						lock_release(&htable[i].lock);
					return;
				}
			}
			else
			{
				if(b2be_dbf.update(b2be_db, qcols, 0, qvals,
							qcols+n_start_update, qvals+n_start_update,
							n_query_update, DB_COLS_NO-n_start_update)< 0)
				{
					LM_ERR("Sql update failed\n");
					if(!no_lock)
						lock_release(&htable[i].lock);
					return;
				}
			}

			dlg->db_flag = NO_UPDATEDB_FLAG;
			dlg = dlg->next;
		}
		if(!no_lock)
			lock_release(&htable[i].lock);
	}
}
Esempio n. 6
0
int wsconn_add(struct receive_info rcv, unsigned int sub_protocol)
{
	int cur_cons, max_cons;
	int id = rcv.proto_reserved1;
	int id_hash = tcp_id_hash(id);
	ws_connection_t *wsc;

	LM_DBG("wsconn_add id [%d]\n", id);

	/* Allocate and fill in new WebSocket connection */
	wsc = shm_malloc(sizeof(ws_connection_t) + BUF_SIZE);
	if (wsc == NULL)
	{
		LM_ERR("allocating shared memory\n");
		return -1;
	}
	memset(wsc, 0, sizeof(ws_connection_t) + BUF_SIZE);
	wsc->id = id;
	wsc->id_hash = id_hash;
	wsc->state = WS_S_OPEN;
	wsc->rcv = rcv;
	wsc->sub_protocol = sub_protocol;
	wsc->run_event = 0;
	wsc->frag_buf.s = ((char*)wsc) + sizeof(ws_connection_t);
	atomic_set(&wsc->refcnt, 0);

	LM_DBG("wsconn_add new wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt));

	WSCONN_LOCK;
	/* Add to WebSocket connection table */
	wsconn_listadd(wsconn_id_hash[wsc->id_hash], wsc, id_next, id_prev);

	/* Add to the end of the WebSocket used list */
	wsc->last_used = (int)time(NULL);
	if (wsconn_used_list->head == NULL)
		wsconn_used_list->head = wsconn_used_list->tail = wsc;
	else
	{
		wsc->used_prev = wsconn_used_list->tail;
		wsconn_used_list->tail->used_next = wsc;
		wsconn_used_list->tail = wsc;
	}
	wsconn_ref(wsc);

	WSCONN_UNLOCK;

	LM_DBG("wsconn_add added to conn_table wsc => [%p], ref => [%d]\n", wsc, atomic_get(&wsc->refcnt));

	/* Update connection statistics */
	lock_get(wsstat_lock);

	update_stat(ws_current_connections, 1);
	cur_cons = get_stat_val(ws_current_connections);
	max_cons = get_stat_val(ws_max_concurrent_connections);
	if (max_cons < cur_cons)
		update_stat(ws_max_concurrent_connections, cur_cons - max_cons);

	if (wsc->sub_protocol == SUB_PROTOCOL_SIP)
	{
		update_stat(ws_sip_current_connections, 1);
		cur_cons = get_stat_val(ws_sip_current_connections);
		max_cons = get_stat_val(ws_sip_max_concurrent_connections);
		if (max_cons < cur_cons)
			update_stat(ws_sip_max_concurrent_connections,
					cur_cons - max_cons);
	}
	else if (wsc->sub_protocol == SUB_PROTOCOL_MSRP)
	{
		update_stat(ws_msrp_current_connections, 1);
		cur_cons = get_stat_val(ws_msrp_current_connections);
		max_cons = get_stat_val(ws_msrp_max_concurrent_connections);
		if (max_cons < cur_cons)
			update_stat(ws_msrp_max_concurrent_connections,
					cur_cons - max_cons);
	}

	lock_release(wsstat_lock);

	return 0;
}
Esempio n. 7
0
void releaseUser(struct lock *lock){
	lock_release(lock);
}
/**
 * UnLocks the dialog counter variable
 */
inline void s_dialog_count_unlock()
{
        lock_release(scscf_dialog_count_lock);
}
Esempio n. 9
0
static void mdd_lockdep_pd_release(struct mdd_object *obj)
{
        lock_release(&obj->dep_map, 0, RETIP);
}
Esempio n. 10
0
void timer_send_notify(unsigned int ticks,void *param)
{
	db_key_t query_cols[2], update_cols[1], result_cols[7];
	db_val_t query_vals[2], update_vals[1];
	int did_col, resource_uri_col, auth_state_col, reason_col,
		body_col, ctype_col;
	int n_result_cols= 0, i;
	db_res_t *result= NULL;
	char* prev_did= NULL, * curr_did= NULL;
	db_row_t *row;	
	db_val_t *row_vals;
	char* resource_uri;
	str body;
	str callid, to_tag, from_tag;
	xmlDocPtr rlmi_doc= NULL;
	xmlNodePtr list_node= NULL, instance_node= NULL, resource_node;
	unsigned int hash_code= 0;
	int len;
	int size= BUF_REALLOC_SIZE, buf_len= 0;
	char* buf= NULL, *auth_state= NULL;
	int contor= 0, auth_state_flag;
	str bstr= {0, 0};
	str rlmi_cont= {0, 0}, multi_cont;
	subs_t* s, *dialog= NULL;
	char* rl_uri= NULL;
	char* str_aux = NULL;
	str ctype, cid;
	int add_len;

	query_cols[0]= &str_updated_col;
	query_vals[0].type = DB_INT;
	query_vals[0].nul = 0;
	query_vals[0].val.int_val= UPDATED_TYPE; 

	result_cols[did_col= n_result_cols++]= &str_rlsubs_did_col;
	result_cols[resource_uri_col= n_result_cols++]= &str_resource_uri_col;
	result_cols[auth_state_col= n_result_cols++]= &str_auth_state_col;
	result_cols[ctype_col= n_result_cols++]= &str_content_type_col;
	result_cols[reason_col= n_result_cols++]= &str_reason_col;
	result_cols[body_col= n_result_cols++]= &str_presence_state_col;

	/* query in alfabetical order after rlsusbs_did 
	 * (resource list Subscribe dialog indentifier)*/

	if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto done;
	}

	if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
					1, n_result_cols, &str_rlsubs_did_col, &result)< 0)
	{
		LM_ERR("in sql query\n");
		goto done;
	}
	if(result== NULL || result->n<= 0)
		goto done;

	/* update the rlpres table */
	update_cols[0]= &str_updated_col;
	update_vals[0].type = DB_INT;
	update_vals[0].nul = 0;
	update_vals[0].val.int_val= NO_UPDATE_TYPE; 

	if (rls_dbf.use_table(rls_db, &rlpres_table) < 0) 
	{
		LM_ERR("in use_table\n");
		goto error;
	}
	if(rls_dbf.update(rls_db, query_cols, 0, query_vals, update_cols,
					update_vals, 1, 1)< 0)
	{
		LM_ERR("in sql update\n");
		goto error;
	}

	/* generate the boundary string */

	bstr.s= generate_string((int)time(NULL), BOUNDARY_STRING_LEN);
	if(bstr.s == NULL)
	{
		LM_ERR("failed to generate random string\n");
		goto error;
	}
	bstr.len= strlen(bstr.s);

	/* for the multipart body , use here also an initial allocated
	 * and reallocated on need buffer */
	buf= pkg_malloc(size);
	if(buf== NULL)
	{
		ERR_MEM(PKG_MEM_STR);
	}

	LM_DBG("found %d records with updated state\n", result->n);
	for(i= 0; i< result->n; i++)
	{
		row = &result->rows[i];
		row_vals = ROW_VALUES(row);
		
		curr_did=     (char*)row_vals[did_col].val.string_val;
		resource_uri= (char*)row_vals[resource_uri_col].val.string_val;
		auth_state_flag=     row_vals[auth_state_col].val.int_val;
		body.s=   (char*)row_vals[body_col].val.string_val;
		body.len= strlen(body.s);
		ctype.s = (char*)row_vals[ctype_col].val.string_val;
		ctype.len = strlen(ctype.s);

		/* if all the info for one dialog have been collected -> send notify */
		/* the 'dialog' variable must be filled with the dialog info */
		/* 'buf' must contain the body */
		if(prev_did!= NULL && strcmp(prev_did, curr_did)) 
		{
			xmlDocDumpMemory(rlmi_doc,(xmlChar**)(void*)&rlmi_cont.s,
				&rlmi_cont.len);
		
			multi_cont.s= buf;
			multi_cont.len= buf_len;
			 
			if(agg_body_sendn_update(&dialog->pres_uri, bstr, &rlmi_cont, 
						 (buf_len==0)?NULL:&multi_cont, dialog, hash_code)<0)
			 {
				 LM_ERR("in function agg_body_sendn_update\n");
				 goto error;
			 }
			xmlFree(rlmi_cont.s);

			xmlFreeDoc(rlmi_doc);
			rlmi_doc= NULL;
			pkg_free(rl_uri);
			rl_uri= NULL;
			pkg_free(dialog);
			dialog= NULL;
		}

		/* for the new dialog -> search the dialog info and 
		 * fill the dialog structure and start a new rlmi document */
		if(prev_did== NULL || strcmp(prev_did, curr_did)) 
		{
			/* search the subscription in rlsubs_table*/
			if( parse_rlsubs_did(curr_did, &callid, &from_tag, &to_tag)< 0)
			{
				LM_ERR("bad format for "
					"resource list Subscribe dialog indentifier(rlsubs did)\n");
				prev_did = NULL;
				continue;

			}
			hash_code= core_hash(&callid, &to_tag, hash_size);
		
			lock_get(&rls_table[hash_code].lock);
			s= pres_search_shtable(rls_table,callid,to_tag,from_tag,hash_code);
			if(s== NULL)
			{
				LM_DBG("record not found in hash_table [rlsubs_did]= %s\n",
						curr_did);
				LM_DBG("callid= %.*s\tfrom_tag= %.*s\tto_tag= %.*s\n",
						callid.len, callid.s,from_tag.len,from_tag.s,
						to_tag.len,to_tag.s);
				lock_release(&rls_table[hash_code].lock);
				prev_did = NULL;
				continue;
			}
			LM_DBG("Found rl-subs record in hash table\n");
					
			/* save dialog info and rl_uri*/
			dialog= pres_copy_subs(s, PKG_MEM_TYPE);
			if(dialog== NULL)
			{	
				LM_ERR("while copying subs_t structure\n");
				lock_release(&rls_table[hash_code].lock);
				goto done;
			}
			dialog->expires-= (int)time(NULL);
			lock_release(&rls_table[hash_code].lock);

			/* make new rlmi and multipart documents */
			rlmi_doc= xmlNewDoc(BAD_CAST "1.0");
			if(rlmi_doc== NULL)
			{
				LM_ERR("when creating new xml doc\n");
				goto done;
			}
			list_node= xmlNewNode(NULL, BAD_CAST "list");
			if(list_node== NULL)
			{
				LM_ERR("while creating new xml node\n");
				goto done;
			}
			rl_uri= (char*)pkg_malloc((dialog->pres_uri.len+ 1)* sizeof(char));
			if(rl_uri==  NULL)
			{
				ERR_MEM(PKG_MEM_STR);
			}
			memcpy(rl_uri, dialog->pres_uri.s, dialog->pres_uri.len);
			rl_uri[dialog->pres_uri.len]= '\0';

			xmlNewProp(list_node, BAD_CAST "uri", BAD_CAST rl_uri);
			xmlNewProp(list_node, BAD_CAST "xmlns", BAD_CAST "urn:ietf:params:xml:ns:rlmi");
			xmlNewProp(list_node, BAD_CAST "version", BAD_CAST int2str(dialog->version, &len));
			xmlNewProp(list_node, BAD_CAST "fullState", BAD_CAST "false");

			xmlDocSetRootElement(rlmi_doc, list_node);
			buf_len= 0;

			/* !!!! for now I will include the auth state without checking if 
			 * it has changed - > in future chech if it works */		
		}		

		/* add a node in rlmi_doc and if any presence state registered add 
		 * it in the buffer */
		
		resource_node= xmlNewChild(list_node,NULL,BAD_CAST "resource", NULL);
		if(resource_node== NULL)
		{
			LM_ERR("when adding resource child\n");
			goto done;
		}
		xmlNewProp(resource_node, BAD_CAST "uri", BAD_CAST resource_uri);
			
		/* there might be more records with the same uri- more instances-
		 * search and add them all */
		
		contor= 0;
		while(1)
		{
			contor++;
			cid.s= NULL;
			instance_node= xmlNewChild(resource_node, NULL, 
					BAD_CAST "instance", NULL);
			if(instance_node== NULL)
			{
				LM_ERR("while adding instance child\n");
				goto error;
			}
			str_aux = generate_string(contor, 8);
			if(str_aux == NULL)
			{
				LM_ERR("failed to create random string\n");
				goto error;
			}
			xmlNewProp(instance_node, BAD_CAST "id",
					BAD_CAST str_aux);
			pkg_free(str_aux);

			auth_state= get_auth_string(auth_state_flag);
			if(auth_state== NULL)
			{
				LM_ERR("bad authorization status flag\n");
				goto error;
			}
			xmlNewProp(instance_node, BAD_CAST "state", BAD_CAST auth_state);
		
			if(auth_state_flag & ACTIVE_STATE)
			{
				cid.s= generate_cid(resource_uri, strlen(resource_uri));
				cid.len = strlen(cid.s);
				xmlNewProp(instance_node, BAD_CAST "cid", BAD_CAST cid.s);
			}
			else
			if(auth_state_flag & TERMINATED_STATE)
			{
				xmlNewProp(instance_node, BAD_CAST "reason",
					BAD_CAST row_vals[resource_uri_col].val.string_val);
			}
		
			/* add in the multipart buffer */
			if(cid.s)
			{
				APPEND_MULTIPART_BODY();
				pkg_free(cid.s);
				cid.s = NULL;
			}

			i++;
			if(i== result->n)
			{
				i--;
				break;
			}

			row = &result->rows[i];
			row_vals = ROW_VALUES(row);
	
			if(strncmp(row_vals[resource_uri_col].val.string_val,resource_uri,
					strlen(resource_uri)) || strncmp(curr_did, 
					row_vals[did_col].val.string_val, strlen(curr_did)))
			{
				i--;
				break;
			}
			resource_uri= (char*)row_vals[resource_uri_col].val.string_val;
			auth_state_flag=     row_vals[auth_state_col].val.int_val;
			body.s=   (char*)row_vals[body_col].val.string_val;
			body.len = strlen(body.s);
		}

		prev_did= curr_did;
	}

	if(rlmi_doc)
	{
		xmlDocDumpMemory( rlmi_doc,(xmlChar**)(void*)&rlmi_cont.s,
		&rlmi_cont.len);
		
		multi_cont.s= buf;
		multi_cont.len= buf_len;
	
		 if(agg_body_sendn_update(&dialog->pres_uri, bstr, &rlmi_cont, 
			 (buf_len==0)?NULL:&multi_cont, dialog, hash_code)<0)
		 {
			 LM_ERR("in function agg_body_sendn_update\n");
			 goto error;
		}
		xmlFree(rlmi_cont.s);
		pkg_free(rl_uri);
		rl_uri= NULL;
		pkg_free(dialog);
		dialog= NULL;
	}

error:
done:
	if(result)
		rls_dbf.free_result(rls_db, result);
	if(rlmi_doc)
		xmlFreeDoc(rlmi_doc);
	if(rl_uri)
		pkg_free(rl_uri);
	if(bstr.s)
		pkg_free(bstr.s);
		
	if(buf)
		pkg_free(buf);
	if(dialog)
		pkg_free(dialog);
	return;
}
Esempio n. 11
0
/**
 * UnLocks the required slot of the dialog hash table
 * @param hash - index of the slot to unlock
 */
inline void d_unlock(unsigned int hash)
{
	lock_release(s_dialogs[(hash)].lock);
//	LOG(L_CRIT,"RELEASED %d\n",hash);	
}
Esempio n. 12
0
/**
 * Timer function for peer management.
 * This is registered as a timer by peer_manager_init() and gets called every
 * #PEER_MANAGER_TIMER seconds. Then it looks on what changed and triggers events.
 * @param now - time of call
 * @param ptr - generic pointer for timers - not used
 */
int peer_timer(time_t now,void *ptr)
{
	peer *p,*n;
	int i;
	LM_DBG("peer_timer(): taking care of peers...\n");
	lock_get(peer_list_lock);
	p = peer_list->head;
	while(p){
		lock_get(p->lock);
		n = p->next;

		if (p->disabled && (p->state != Closed || p->state != Closing)) {
			LM_DBG("Peer [%.*s] has been disabled - shutting down\n", p->fqdn.len, p->fqdn.s);
			if (p->state == I_Open) sm_process(p, Stop, 0, 1, p->I_sock);
			if (p->state == R_Open) sm_process(p, Stop, 0, 1, p->R_sock);
			lock_release(p->lock);
			p = n;
			continue;
		}

		if (p->activity+config->tc<=now){
			LM_INFO("peer_timer(): Peer %.*s \tState %d \n",p->fqdn.len,p->fqdn.s,p->state);
			switch (p->state){
				/* initiating connection */
				case Closed:
					if (p->is_dynamic && config->drop_unknown_peers){
						remove_peer(p);
						free_peer(p,1);
						break;
					}
					if (!p->disabled) {
						touch_peer(p);
						sm_process(p,Start,0,1,0);
					}
					break;
				/* timeouts */
				case Wait_Conn_Ack:
				case Wait_I_CEA:
				case Closing:
				case Wait_Returns:
				case Wait_Conn_Ack_Elect:
					touch_peer(p);
					sm_process(p,Timeout,0,1,0);
					break;
				/* inactivity detected */
				case I_Open:
				case R_Open:
					if (p->waitingDWA){
						p->waitingDWA = 0;
						if (p->state==I_Open) sm_process(p,I_Peer_Disc,0,1,p->I_sock);
						if (p->state==R_Open) sm_process(p,R_Peer_Disc,0,1,p->R_sock);
						LM_WARN("Inactivity on peer [%.*s] and no DWA, Closing peer...\n", p->fqdn.len, p->fqdn.s);
					} else {
						p->waitingDWA = 1;
						Snd_DWR(p);
						touch_peer(p);
						LM_DBG("Inactivity on peer [%.*s], sending DWR... - if we don't get a reply, the peer will be closed\n", p->fqdn.len, p->fqdn.s);
					}
					break;
				/* ignored states */
				/* unknown states */
				default:
					LM_ERR("peer_timer(): Peer %.*s inactive  in state %d\n",
						p->fqdn.len,p->fqdn.s,p->state);
			}
		}
		lock_release(p->lock);
		p = n;
	}
	lock_release(peer_list_lock);
	log_peer_list();
	i = config->tc/5;
	if (i<=0) i=1;
	return i;
}
Esempio n. 13
0
static void db_update(unsigned int ticks,void *param)
{
	ua_pres_t* p= NULL;
	db_key_t q_cols[20], result_cols[1];
	db1_res_t *res= NULL;
	db_key_t db_cols[5];
	db_val_t q_vals[20], db_vals[5];
	db_op_t  db_ops[1] ;
	int n_query_cols= 0, n_query_update= 0;
	int n_update_cols= 0;
	int i;
	int puri_col,pid_col,expires_col,flag_col,etag_col,tuple_col,event_col;
	int watcher_col,callid_col,totag_col,fromtag_col,record_route_col,cseq_col;
	int no_lock= 0, contact_col, desired_expires_col, extra_headers_col;
	int remote_contact_col, version_col;

	if (dbmode==PUA_DB_ONLY) return;

	if(ticks== 0 && param == NULL)
		no_lock= 1;

	/* cols and values used for insert */
	q_cols[puri_col= n_query_cols] = &str_pres_uri_col;
	q_vals[puri_col].type = DB1_STR;
	q_vals[puri_col].nul = 0;
	n_query_cols++;

	q_cols[pid_col= n_query_cols] = &str_pres_id_col;	
	q_vals[pid_col].type = DB1_STR;
	q_vals[pid_col].nul = 0;
	n_query_cols++;

	q_cols[flag_col= n_query_cols] = &str_flag_col;
	q_vals[flag_col].type = DB1_INT;
	q_vals[flag_col].nul = 0;
	n_query_cols++;

	q_cols[event_col= n_query_cols] = &str_event_col;
	q_vals[event_col].type = DB1_INT;
	q_vals[event_col].nul = 0;
	n_query_cols++;

	q_cols[watcher_col= n_query_cols] = &str_watcher_uri_col;
	q_vals[watcher_col].type = DB1_STR;
	q_vals[watcher_col].nul = 0;
	n_query_cols++;

	q_cols[callid_col= n_query_cols] = &str_call_id_col;
	q_vals[callid_col].type = DB1_STR;
	q_vals[callid_col].nul = 0;
	n_query_cols++;

	q_cols[totag_col= n_query_cols] = &str_to_tag_col;
	q_vals[totag_col].type = DB1_STR;
	q_vals[totag_col].nul = 0;
	n_query_cols++;

	q_cols[fromtag_col= n_query_cols] = &str_from_tag_col;
	q_vals[fromtag_col].type = DB1_STR;
	q_vals[fromtag_col].nul = 0;
	n_query_cols++;

	q_cols[etag_col= n_query_cols] = &str_etag_col;
	q_vals[etag_col].type = DB1_STR;
	q_vals[etag_col].nul = 0;
	n_query_cols++;	

	q_cols[tuple_col= n_query_cols] = &str_tuple_id_col;
	q_vals[tuple_col].type = DB1_STR;
	q_vals[tuple_col].nul = 0;
	n_query_cols++;

	q_cols[cseq_col= n_query_cols]= &str_cseq_col;
	q_vals[cseq_col].type = DB1_INT;
	q_vals[cseq_col].nul = 0;
	n_query_cols++;

	q_cols[expires_col= n_query_cols] = &str_expires_col;
	q_vals[expires_col].type = DB1_INT;
	q_vals[expires_col].nul = 0;
	n_query_cols++;

	q_cols[desired_expires_col= n_query_cols] = &str_desired_expires_col;
	q_vals[desired_expires_col].type = DB1_INT;
	q_vals[desired_expires_col].nul = 0;
	n_query_cols++;

	q_cols[record_route_col= n_query_cols] = &str_record_route_col;
	q_vals[record_route_col].type = DB1_STR;
	q_vals[record_route_col].nul = 0;
	n_query_cols++;

	q_cols[contact_col= n_query_cols] = &str_contact_col;
	q_vals[contact_col].type = DB1_STR;
	q_vals[contact_col].nul = 0;
	n_query_cols++;

	q_cols[remote_contact_col= n_query_cols] = &str_remote_contact_col;
	q_vals[remote_contact_col].type = DB1_STR;
	q_vals[remote_contact_col].nul = 0;
	n_query_cols++;

	q_cols[version_col= n_query_cols] = &str_version_col;
	q_vals[version_col].type = DB1_INT;
	q_vals[version_col].nul = 0;
	n_query_cols++;

	/* must keep this the last  column to be inserted */
	q_cols[extra_headers_col= n_query_cols] = &str_extra_headers_col;
	q_vals[extra_headers_col].type = DB1_STR;
	q_vals[extra_headers_col].nul = 0;
	n_query_cols++;

	/* cols and values used for update */
	db_cols[0]= &str_expires_col;
	db_vals[0].type = DB1_INT;
	db_vals[0].nul = 0;

	db_cols[1]= &str_cseq_col;
	db_vals[1].type = DB1_INT;
	db_vals[1].nul = 0;

	db_cols[2]= &str_etag_col;
	db_vals[2].type = DB1_STR;
	db_vals[2].nul = 0;

	db_cols[3]= &str_desired_expires_col;
	db_vals[3].type = DB1_INT;
	db_vals[3].nul = 0;

	db_cols[4]= &str_version_col;
	db_vals[4].type = DB1_INT;
	db_vals[4].nul = 0;

	result_cols[0]= &str_expires_col;

	if(pua_db== NULL)
	{
		LM_ERR("null database connection\n");
		return;
	}

	if(pua_dbf.use_table(pua_db, &db_table)< 0)
	{
		LM_ERR("in use table\n");
		return ;
	}

	for(i=0; i<HASH_SIZE; i++) 
	{
		if(!no_lock)
			lock_get(&HashT->p_records[i].lock);	

		p = HashT->p_records[i].entity->next;
		while(p)
		{
			if((int)p->expires - (int)time(NULL)< 0)	
			{
				p= p->next;
				continue;
			}

			switch(p->db_flag)
			{
				case NO_UPDATEDB_FLAG:
					{
						LM_DBG("NO_UPDATEDB_FLAG\n");
						break;			  
					}

				case UPDATEDB_FLAG:
					{
						LM_DBG("UPDATEDB_FLAG\n");
						n_update_cols= 0;
						n_query_update= 0;

						q_vals[puri_col].val.str_val = *(p->pres_uri);
						n_query_update++;

						q_vals[pid_col].val.str_val = p->id;
						n_query_update++;

						q_vals[flag_col].val.int_val = p->flag;
						n_query_update++;

						q_vals[event_col].val.int_val = p->event;
						n_query_update++;

						if(p->watcher_uri)
						{
							q_vals[watcher_col].val.str_val = *(p->watcher_uri);
							n_query_update++;

							q_vals[callid_col].val.str_val = p->call_id;
							n_query_update++;

							q_vals[totag_col].val.str_val = p->to_tag;
							n_query_update++;

							q_vals[fromtag_col].val.str_val = p->from_tag;
							n_query_update++;
						}

						db_vals[0].val.int_val= p->expires;
						n_update_cols++;

						db_vals[1].val.int_val= p->cseq	;
						n_update_cols++;

						db_vals[2].val.str_val= p->etag	;
						n_update_cols++;

						db_vals[3].val.int_val= p->desired_expires;
						n_update_cols++;

						db_vals[4].val.int_val= p->version;
						n_update_cols++;

						LM_DBG("Updating:n_query_update= %d\tn_update_cols= %d\n",
								n_query_update, n_update_cols);

						if(pua_dbf.query(pua_db, q_cols, 0, q_vals,
									result_cols, n_query_update, 1, 0, &res)< 0)
						{
							LM_ERR("while querying db table pua\n");
							if(!no_lock)
								lock_release(&HashT->p_records[i].lock);
							if(res)
								pua_dbf.free_result(pua_db, res);	
							return ;
						}
						if(res && res->n> 0)
						{																				
							if(pua_dbf.update(pua_db, q_cols, 0, q_vals, db_cols, 
										db_vals, n_query_update, n_update_cols)<0)
							{
								LM_ERR("while updating in database\n");
								if(!no_lock)
									lock_release(&HashT->p_records[i].lock);	
								pua_dbf.free_result(pua_db, res);
								res= NULL;
								return ;
							}
							pua_dbf.free_result(pua_db, res);
							res= NULL;		
						}
						else
						{
							if(res)
							{	
								pua_dbf.free_result(pua_db, res);
								res= NULL;
							}
							LM_DBG("UPDATEDB_FLAG and no record found\n");
							//	p->db_flag= INSERTDB_FLAG;
						}	
						break;	
					}
				case INSERTDB_FLAG:
					{	
						LM_DBG("INSERTDB_FLAG\n");
						q_vals[puri_col].val.str_val = *(p->pres_uri);
						q_vals[pid_col].val.str_val = p->id;
						q_vals[flag_col].val.int_val = p->flag;
						if(p->call_id.s) {
							LM_DBG("p->callid = %.*s\n", p->call_id.len, p->call_id.s);
							q_vals[callid_col].val.str_val = p->call_id;
						} else {
							LM_DBG("p->callid is empty\n");
							q_vals[callid_col].val.str_val.s = "";
							q_vals[callid_col].val.str_val.len = 0;
						}
						q_vals[fromtag_col].val.str_val = p->from_tag;
						q_vals[cseq_col].val.int_val= p->cseq;
						q_vals[expires_col].val.int_val = p->expires;
						q_vals[desired_expires_col].val.int_val = p->desired_expires;
						q_vals[event_col].val.int_val = p->event;
						q_vals[version_col].val.int_val = p->version;

						if((p->watcher_uri))
							q_vals[watcher_col].val.str_val = *(p->watcher_uri);
						else
						{
							q_vals[watcher_col].val.str_val.s = "";
							q_vals[watcher_col].val.str_val.len = 0;
						}

						if(p->tuple_id.s == NULL)
						{
							q_vals[tuple_col].val.str_val.s="";
							q_vals[tuple_col].val.str_val.len=0;
						}
						else
							q_vals[tuple_col].val.str_val = p->tuple_id;

						if(p->etag.s == NULL)
						{
							q_vals[etag_col].val.str_val.s="";
							q_vals[etag_col].val.str_val.len=0;
						}
						else
							q_vals[etag_col].val.str_val = p->etag;

						if (p->to_tag.s == NULL)
						{
							q_vals[totag_col].val.str_val.s="";
							q_vals[totag_col].val.str_val.len=0;
						}
						else
							q_vals[totag_col].val.str_val = p->to_tag;

						if(p->record_route.s== NULL)
						{
							q_vals[record_route_col].val.str_val.s= "";
							q_vals[record_route_col].val.str_val.len = 0;
						}
						else
							q_vals[record_route_col].val.str_val = p->record_route;

						if(p->contact.s == NULL)
						{
							q_vals[contact_col].val.str_val.s = "";
							q_vals[contact_col].val.str_val.len = 0;
						}
						else
							q_vals[contact_col].val.str_val = p->contact;

						if(p->remote_contact.s)
						{
							q_vals[remote_contact_col].val.str_val = p->remote_contact;
							LM_DBG("p->remote_contact = %.*s\n", p->remote_contact.len, p->remote_contact.s);
						}
						else
						{
							q_vals[remote_contact_col].val.str_val.s = "";
							q_vals[remote_contact_col].val.str_val.len = 0;
						}

						if(p->extra_headers)
							q_vals[extra_headers_col].val.str_val = *(p->extra_headers);
						else
						{
							q_vals[extra_headers_col].val.str_val.s = "";
							q_vals[extra_headers_col].val.str_val.len = 0;
						}

						if(pua_dbf.insert(pua_db, q_cols, q_vals,n_query_cols )<0)
						{
							LM_ERR("while inserting in db table pua\n");
							if(!no_lock)
								lock_release(&HashT->p_records[i].lock);
							return ;
						}
						break;
					}

			}
			p->db_flag= NO_UPDATEDB_FLAG;	
			p= p->next;
		}
		if(!no_lock)
			lock_release(&HashT->p_records[i].lock);	
	}

	db_vals[0].val.int_val= (int)time(NULL)- 10;
	db_ops[0]= OP_LT;
	if(pua_dbf.delete(pua_db, db_cols, db_ops, db_vals, 1) < 0)
	{
		LM_ERR("while deleting from db table pua\n");
	}

	return ;
}	
Esempio n. 14
0
static int db_restore(void)
{
	ua_pres_t* p= NULL;
	db_key_t result_cols[19]; 
	db1_res_t *res= NULL;
	db_row_t *row = NULL;	
	db_val_t *row_vals= NULL;
	str pres_uri, pres_id;
	str etag, tuple_id;
	str watcher_uri, call_id;
	str to_tag, from_tag, remote_contact;
	str record_route, contact, extra_headers;
	int size= 0, i;
	int n_result_cols= 0;
	int puri_col,pid_col,expires_col,flag_col,etag_col, desired_expires_col;
	int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col;
	int event_col,contact_col,tuple_col,record_route_col, extra_headers_col;
	int version_col;
	unsigned int hash_code;

	if (dbmode==PUA_DB_ONLY)
	{
		LM_ERR( "db_restore shouldn't be called in PUA_DB_ONLY mode\n" );
		return(-1);
	}

	result_cols[puri_col=n_result_cols++]	= &str_pres_uri_col;
	result_cols[pid_col=n_result_cols++]	= &str_pres_id_col;
	result_cols[expires_col=n_result_cols++]= &str_expires_col;
	result_cols[flag_col=n_result_cols++]	= &str_flag_col;
	result_cols[etag_col=n_result_cols++]	= &str_etag_col;
	result_cols[tuple_col=n_result_cols++]	= &str_tuple_id_col;
	result_cols[watcher_col=n_result_cols++]= &str_watcher_uri_col;
	result_cols[callid_col=n_result_cols++] = &str_call_id_col;
	result_cols[totag_col=n_result_cols++]	= &str_to_tag_col;
	result_cols[fromtag_col=n_result_cols++]= &str_from_tag_col;
	result_cols[cseq_col= n_result_cols++]	= &str_cseq_col;
	result_cols[event_col= n_result_cols++]	= &str_event_col;
	result_cols[record_route_col= n_result_cols++]	= &str_record_route_col;
	result_cols[contact_col= n_result_cols++]	= &str_contact_col;
	result_cols[remote_contact_col= n_result_cols++]	= &str_remote_contact_col;
	result_cols[extra_headers_col= n_result_cols++]	= &str_extra_headers_col;
	result_cols[desired_expires_col= n_result_cols++]	= &str_desired_expires_col;
	result_cols[version_col= n_result_cols++]	= &str_version_col;

	if(!pua_db)
	{
		LM_ERR("null database connection\n");
		return -1;
	}

	if(pua_dbf.use_table(pua_db, &db_table)< 0)
	{
		LM_ERR("in use table\n");
		return -1;
	}

	if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, 0, 0, 0, result_cols,
				0, n_result_cols, 0, &res)< 0)
	{
		LM_ERR("while querrying table\n");
		if(res)
		{
			pua_dbf.free_result(pua_db, res);
			res = NULL;
		}
		return -1;
	}
	if(res==NULL)
		return -1;

	if(res->n<=0)
	{
		LM_INFO("the query returned no result\n");
		pua_dbf.free_result(pua_db, res);
		res = NULL;
		return 0;
	}

	do {
		LM_DBG("found %d db entries\n", res->n);

		for(i =0 ; i< res->n ; i++)
		{
			row = &res->rows[i];
			row_vals = ROW_VALUES(row);

			pres_uri.s= (char*)row_vals[puri_col].val.string_val;
			pres_uri.len = strlen(pres_uri.s);

			LM_DBG("pres_uri= %.*s\n", pres_uri.len, pres_uri.s);

			memset(&etag,			 0, sizeof(str));
			memset(&tuple_id,		 0, sizeof(str));
			memset(&watcher_uri,	 0, sizeof(str));
			memset(&call_id,		 0, sizeof(str));
			memset(&to_tag,			 0, sizeof(str));
			memset(&from_tag,		 0, sizeof(str));
			memset(&record_route,	 0, sizeof(str));
			memset(&pres_id,         0, sizeof(str));
			memset(&contact,         0, sizeof(str));
			memset(&remote_contact,         0, sizeof(str));
			memset(&extra_headers,   0, sizeof(str));

			pres_id.s= (char*)row_vals[pid_col].val.string_val;
			if(pres_id.s)
				pres_id.len = strlen(pres_id.s);

			if(row_vals[etag_col].val.string_val)
			{
				etag.s= (char*)row_vals[etag_col].val.string_val;
				etag.len = strlen(etag.s);

				tuple_id.s= (char*)row_vals[tuple_col].val.string_val;
				tuple_id.len = strlen(tuple_id.s);
			}

			if(row_vals[watcher_col].val.string_val)
			{	
				watcher_uri.s= (char*)row_vals[watcher_col].val.string_val;
				watcher_uri.len = strlen(watcher_uri.s);

				call_id.s= (char*)row_vals[callid_col].val.string_val;
				call_id.len = strlen(call_id.s);

				to_tag.s= (char*)row_vals[totag_col].val.string_val;
				to_tag.len = strlen(to_tag.s);

				from_tag.s= (char*)row_vals[fromtag_col].val.string_val;
				from_tag.len = strlen(from_tag.s);

				if(row_vals[record_route_col].val.string_val)
				{
					record_route.s= (char*)row_vals[record_route_col].val.string_val;
					record_route.len= strlen(record_route.s);
				}	

				contact.s= (char*)row_vals[contact_col].val.string_val;
				contact.len = strlen(contact.s);

				remote_contact.s= (char*)row_vals[remote_contact_col].val.string_val;
				remote_contact.len = strlen(remote_contact.s);
			}
			extra_headers.s= (char*)row_vals[extra_headers_col].val.string_val;
			if(extra_headers.s)
				extra_headers.len= strlen(extra_headers.s);
			else
				extra_headers.len= 0;

			size= sizeof(ua_pres_t)+ sizeof(str)+ (pres_uri.len+ pres_id.len+
					tuple_id.len)* sizeof(char);
			if(extra_headers.s)
				size+= sizeof(str)+ extra_headers.len* sizeof(char);

			if(watcher_uri.s)
				size+= sizeof(str)+ (watcher_uri.len+ call_id.len+ to_tag.len+
						from_tag.len+ record_route.len+ contact.len)* sizeof(char);

			p= (ua_pres_t*)shm_malloc(size);
			if(p== NULL)
			{
				LM_ERR("no more share memmory");
				goto error;
			}
			memset(p, 0, size);
			size= sizeof(ua_pres_t);

			p->pres_uri= (str*)((char*)p+ size);
			size+= sizeof(str);
			p->pres_uri->s= (char*)p + size;
			memcpy(p->pres_uri->s, pres_uri.s, pres_uri.len);
			p->pres_uri->len= pres_uri.len;
			size+= pres_uri.len;

			if(pres_id.s)
			{	
				p->id.s= (char*)p + size;
				memcpy(p->id.s, pres_id.s, pres_id.len);
				p->id.len= pres_id.len;
				size+= pres_id.len;
			}
			if(tuple_id.s && tuple_id.len)
			{
				p->tuple_id.s= (char*)p + size;
				memcpy(p->tuple_id.s, tuple_id.s, tuple_id.len);
				p->tuple_id.len= tuple_id.len;
				size+= tuple_id.len;
			}	

			if(watcher_uri.s && watcher_uri.len)
			{	
				p->watcher_uri= (str*)((char*)p+ size);
				size+= sizeof(str);

				p->watcher_uri->s= (char*)p+ size;
				memcpy(p->watcher_uri->s, watcher_uri.s, watcher_uri.len);
				p->watcher_uri->len= watcher_uri.len;
				size+= watcher_uri.len;

				p->to_tag.s= (char*)p+ size;
				memcpy(p->to_tag.s, to_tag.s, to_tag.len);
				p->to_tag.len= to_tag.len;
				size+= to_tag.len;

				p->from_tag.s= (char*)p+ size;
				memcpy(p->from_tag.s, from_tag.s, from_tag.len);
				p->from_tag.len= from_tag.len;
				size+= from_tag.len;

				p->call_id.s= (char*)p + size;
				memcpy(p->call_id.s, call_id.s, call_id.len);
				p->call_id.len= call_id.len;
				size+= call_id.len;

				if(record_route.s && record_route.len)
				{
					p->record_route.s= (char*)p + size;
					memcpy(p->record_route.s, record_route.s, record_route.len);
					p->record_route.len= record_route.len;
					size+= record_route.len;
				}
				p->contact.s= (char*)p + size;
				memcpy(p->contact.s, contact.s, contact.len);
				p->contact.len= contact.len;
				size+= contact.len;

				p->cseq= row_vals[cseq_col].val.int_val;

				p->remote_contact.s= (char*)shm_malloc(remote_contact.len* sizeof(char));
				if(p->remote_contact.s== NULL)
				{
					LM_ERR("No more shared memory\n");
					goto error;
				}
				memcpy(p->remote_contact.s, remote_contact.s, remote_contact.len);
				p->remote_contact.len= remote_contact.len;

				p->version= row_vals[version_col].val.int_val;
			}

			if(extra_headers.s)
			{
				p->extra_headers= (str*)((char*)p+ size);
				size+= sizeof(str);
				p->extra_headers->s= (char*)p+ size;
				memcpy(p->extra_headers->s, extra_headers.s, extra_headers.len);
				p->extra_headers->len= extra_headers.len;
				size+= extra_headers.len;
			}

			LM_DBG("size= %d\n", size);
			p->event= row_vals[event_col].val.int_val;
			p->expires= row_vals[expires_col].val.int_val;
			p->desired_expires= row_vals[desired_expires_col].val.int_val;
			p->flag|=	row_vals[flag_col].val.int_val;

			memset(&p->etag, 0, sizeof(str));
			if(etag.s && etag.len)
			{
				/* alloc separately */
				p->etag.s= (char*)shm_malloc(etag.len* sizeof(char));
				if(p->etag.s==  NULL)
				{
					LM_ERR("no more share memory\n");
					goto error;
				}	
				memcpy(p->etag.s, etag.s, etag.len);
				p->etag.len= etag.len;
			}

			print_ua_pres(p);

			hash_code= core_hash(p->pres_uri, p->watcher_uri, HASH_SIZE);
			lock_get(&HashT->p_records[hash_code].lock);
			insert_htable(p, hash_code);
			lock_release(&HashT->p_records[hash_code].lock);
		}

	} while((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
			&& (RES_ROW_N(res)>0));

	pua_dbf.free_result(pua_db, res);
	res = NULL;

	if(pua_dbf.delete(pua_db, 0, 0 , 0, 0) < 0)
	{
		LM_ERR("while deleting information from db\n");
		goto error;
	}

	return 0;

error:
	if(res)
		pua_dbf.free_result(pua_db, res);

	if(p)
		shm_free(p);
	return -1;
}
Esempio n. 15
0
static int b2bl_add_tuple(b2bl_tuple_t* tuple, str* params[])
{
	b2bl_tuple_t* shm_tuple= NULL;
	unsigned int hash_index, local_index;
	str* b2bl_key;
	b2bl_entity_id_t* entity;
	int i;
	b2b_notify_t cback;
	str* client_id = NULL;
	unsigned int logic_restored = 0;

	LM_DBG("Add tuple key [%.*s]\n", tuple->key->len, tuple->key->s);
	if(b2bl_parse_key(tuple->key, &hash_index, &local_index)< 0)
	{
		LM_ERR("Wrong formatted b2b logic key\n");
		return -1;
	}
	shm_tuple = b2bl_insert_new(NULL, hash_index, tuple->scenario, params,
			(tuple->sdp.s?&tuple->sdp:NULL), NULL, local_index,
			&b2bl_key, UPDATEDB_FLAG);
	if(shm_tuple == NULL)
	{
		LM_ERR("Failed to insert new tuple\n");
		return -1;
	}
	shm_tuple->lifetime = tuple->lifetime;
	lock_release(&b2bl_htable[hash_index].lock);
	shm_tuple->scenario_state= tuple->scenario_state;
	shm_tuple->next_scenario_state= tuple->next_scenario_state;

	/* add entities */
	for(i=0; i< MAX_BRIDGE_ENT; i++)
	{
		if(!tuple->bridge_entities[i]->to_uri.len)
			continue;
		LM_DBG("Restore logic info for tuple:entity [%.*s][%d]\n",
				b2bl_key->len, b2bl_key->s, i);

		if(tuple->bridge_entities[i]->type == B2B_SERVER)
			cback = b2b_server_notify;
		else
			cback = b2b_client_notify;

		/* restore to the entities from b2b_entities module
		 * the parameter and callback function */
		if(b2b_api.restore_logic_info(tuple->bridge_entities[i]->type,
			&tuple->bridge_entities[i]->key, cback)< 0)
			LM_WARN("Failed to restore logic info for tuple:entity [%.*s][%d]\n",
				b2bl_key->len, b2bl_key->s, i);
		else
			logic_restored = 1;

		entity= b2bl_create_new_entity(tuple->bridge_entities[i]->type,
			&tuple->bridge_entities[i]->key,&tuple->bridge_entities[i]->to_uri,
			&tuple->bridge_entities[i]->from_uri, 0, &tuple->bridge_entities[i]->scenario_id, 0);
		if(client_id)
			pkg_free(client_id);
		if(entity == NULL)
		{
			LM_ERR("Failed to create entity %d\n", i);
			goto error;
		}
		shm_tuple->bridge_entities[i]= entity;
		/* put the pointer in clients or servers array */
		// FIXME: check if the restore logic is ok
		if(tuple->bridge_entities[i]->type == B2B_SERVER)
		{
			if (shm_tuple->servers[0])
				shm_tuple->servers[1] = entity;
			else
				shm_tuple->servers[0] = entity;
		}
		else
		{
			if (shm_tuple->clients[0])
				shm_tuple->clients[1] = entity;
			else
				shm_tuple->clients[0] = entity;
		}
	}
	if(shm_tuple->bridge_entities[1])
		shm_tuple->bridge_entities[1]->peer = shm_tuple->bridge_entities[0];
	if(shm_tuple->bridge_entities[0])
		shm_tuple->bridge_entities[0]->peer = shm_tuple->bridge_entities[1];

	/* Mark tuple without entities as expired */
	if(logic_restored==0)
		shm_tuple->lifetime = 1;

	return 0;
error:
	shm_free(shm_tuple);
	return -1;
}
Esempio n. 16
0
int
as_copy(struct addrspace *old, struct addrspace **ret)
{
    struct addrspace *newas;

    newas = as_create();
    if (newas==NULL) {
        return ENOMEM;
    }

    //	kprintf(" **** inside as copy ****  \n");
    //	spinlock_acquire(newas->as_splock);
    //	spinlock_acquire(old->as_splock);

    if(use_small_lock == true && swapping_started == true)
    {
        lock_acquire(newas->as_lock);
        lock_acquire(old->as_lock);
    }
    else if(use_big_lock == true && swapping_started == true)
        lock_acquire(as_lock);
    struct as_region* r_old = old->as_region_list;
    while(r_old != NULL)
    {
        struct as_region* r_new = (struct as_region*)kmalloc(sizeof(struct as_region));
        if(r_new == NULL)
        {
            if(use_big_lock == true && swapping_started == true)
                lock_release(as_lock);
            else if(use_small_lock == true && swapping_started == true)
            {
                lock_release(old->as_lock);
                lock_release(newas->as_lock);
            }
            //spinlock_release(old->as_splock);
            //spinlock_release(newas->as_splock);
            as_destroy(newas);
            return ENOMEM;
        }

        r_new->region_base = r_old->region_base;
        r_new->region_npages = r_old->region_npages;
        r_new->can_read = r_old->can_read;
        r_new->can_write = r_old->can_write;
        r_new->can_execute = r_old->can_execute;

        int ret = region_list_add_node(&newas->as_region_list,r_new);
        if(ret == -1)
        {
            if(use_big_lock == true && swapping_started == true)
                lock_release(as_lock);
            else if(use_small_lock == true  && swapping_started == true)
            {
                lock_release(old->as_lock);
                lock_release(newas->as_lock);
            }
            //	spinlock_release(old->as_splock);
            //	spinlock_release(newas->as_splock);
            as_destroy(newas);
            return ENOMEM;
        }
        r_old = r_old->next;
    }

    struct page_table_entry* p_old = old->as_page_list;
    while(p_old != NULL)
    {
        struct page_table_entry* p_new = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry));
        if(p_new == NULL)
        {
            if(use_big_lock == true && swapping_started == true)
                lock_release(as_lock);
            else if(use_small_lock == true && swapping_started == true)
            {
                lock_release(old->as_lock);
                lock_release(newas->as_lock);
            }
            //		spinlock_release(old->as_splock);
            //		spinlock_release(newas->as_splock);
            as_destroy(newas);

            return ENOMEM;
        }
        p_new->vaddr = p_old->vaddr;
        p_new->swap_pos = -1;

        KASSERT(p_old->page_state != SWAPPING);
        while(p_old->page_state == SWAPPING)
        {

            thread_yield();

        }

        //	if(!spinlock_do_i_hold)
        //	KASSERT(p_old->page_state != SWAPPING);

        if(p_old->page_state == MAPPED)
        {
            if(use_page_lock == true && swapping_started == true)
                lock_acquire(coremap[(p_old->paddr)/PAGE_SIZE].page_lock);

            if(p_old->page_state == MAPPED)
            {
                paddr_t paddr = get_user_page(p_old->vaddr, false, newas);
                KASSERT(p_old->page_state == MAPPED);
                //	int spl = splhigh();
                if(use_small_lock == true && swapping_started == true)
                {
                    if(lock_do_i_hold(newas->as_lock) == false)
                        lock_acquire(newas->as_lock);
                    if(lock_do_i_hold(old->as_lock) == false)
                        lock_acquire(newas->as_lock);
                }
                else if(use_big_lock == true && swapping_started == true)
                {
                    if(lock_do_i_hold(as_lock) == false)
                        lock_acquire(as_lock);
                }
                if(paddr == 0)
                {
                    if(use_big_lock == true && swapping_started == true)
                        lock_release(as_lock);
                    else if(use_small_lock == true && swapping_started == true)
                    {
                        lock_release(old->as_lock);
                        lock_release(newas->as_lock);
                    }
                    //				spinlock_release(old->as_splock);
                    //				spinlock_release(newas->as_splock);
                    as_destroy(newas);
                    return ENOMEM;
                }
                uint32_t old_index = p_old->paddr/PAGE_SIZE;
                KASSERT(coremap[old_index].is_victim == false);
                KASSERT(coremap[paddr/PAGE_SIZE].is_victim == false);
                memmove((void*)PADDR_TO_KVADDR(paddr),
                        (const void *)PADDR_TO_KVADDR(p_old->paddr), //use this? or PADDR_TO_KVADDR like dumbvm does?. But why does dumbvm do that in the first place.
                        PAGE_SIZE);									// i know why, cannot call functions on user memory addresses. So convert it into a kv address.
                // the function will translate it into a physical address again and free it. ugly Hack. but no other way.

                p_new->paddr = paddr;
                p_new->page_state = MAPPED;

                //	splx(spl);

                int ret = page_list_add_node(&newas->as_page_list,p_new);
                if(ret == -1)
                {
                    if(use_big_lock == true && swapping_started == true)
                        lock_release(as_lock);
                    else if(use_small_lock == true && swapping_started == true)
                    {
                        lock_release(old->as_lock);
                        lock_release(newas->as_lock);
                    }
                    //			spinlock_release(old->as_splock);
                    //			spinlock_release(newas->as_splock);
                    as_destroy(newas);
                    return ENOMEM;
                }

                if(use_page_lock == true && swapping_started == true)
                {

                    if(lock_do_i_hold(coremap[paddr/PAGE_SIZE].page_lock) == true)
                        lock_release(coremap[paddr/PAGE_SIZE].page_lock);


                    if(lock_do_i_hold(coremap[(p_old->paddr/PAGE_SIZE)].page_lock) == true)
                        lock_release(coremap[(p_old->paddr/PAGE_SIZE)].page_lock);
                }

            }
        }

        if(p_old->page_state == SWAPPED)
        {
            // this page is in disk, so we need to create a copy of that page somewhere in disk and then update the page table entry of the new process.
            // going with the disk->memory->disk approach suggested in a recitation video by jinghao shi.
            // Allocate a buffer at vm_bootstrap of size 4k (1 page). Use this buffer to temporarily copy data from disk to here and then to disk again
            // then clear the buffer. This buffer is a shared resource, so we need a lock around it.

            //	kprintf("in as_copy swap code \n");
            //	spinlock_release(old->as_splock);
            //	spinlock_release(newas->as_splock);
            swap_in(p_old->vaddr,old,copy_buffer_vaddr, p_old->swap_pos);
            //	kprintf("completed swap in \n");
            int pos = mark_swap_pos(p_new->vaddr, newas);
            KASSERT(pos != -1);
            int err = write_to_disk(KVADDR_TO_PADDR(copy_buffer_vaddr)/PAGE_SIZE, pos);
            //	kprintf("completed writing to disk \n");
            KASSERT(err == 0);
            //		spinlock_acquire(newas->as_splock);
            //		spinlock_acquire(old->as_splock);
            //	as_zero_region(KVADDR_TO_PADDR(copy_buffer_vaddr),1);
            p_new->page_state = SWAPPED;
            p_new->swap_pos = pos;
            p_new->paddr = 0;


            if(use_page_lock == true && swapping_started == true)
            {

                if(lock_do_i_hold(coremap[(p_old->paddr/PAGE_SIZE)].page_lock) == true)
                    lock_release(coremap[(p_old->paddr/PAGE_SIZE)].page_lock);
            }
        }
        p_old = p_old->next;

    }

    newas->as_heap_start = old->as_heap_start;
    newas->as_heap_end = old->as_heap_end;
    *ret = newas;


    if(use_big_lock == true && swapping_started == true)
        lock_release(as_lock);
    else if(use_small_lock == true && swapping_started == true)
    {
        lock_release(old->as_lock);
        lock_release(newas->as_lock);
    }

//	kprintf("exiting as copy \n");
    //	spinlock_release(old->as_splock);
    //	spinlock_release(newas->as_splock);
    return 0;
}
Esempio n. 17
0
/*
 * Create a semaphore.
 */
static
int
semfs_creat(struct vnode *dirvn, const char *name, bool excl, mode_t mode,
	    struct vnode **resultvn)
{
	struct semfs_vnode *dirsemv = dirvn->vn_data;
	struct semfs *semfs = dirsemv->semv_semfs;
	struct semfs_direntry *dent;
	struct semfs_sem *sem;
	unsigned i, num, empty, semnum;
	int result;

	(void)mode;
	if (!strcmp(name, ".") || !strcmp(name, "..")) {
		return EEXIST;
	}

	lock_acquire(semfs->semfs_dirlock);
	num = semfs_direntryarray_num(semfs->semfs_dents);
	empty = num;
	for (i=0; i<num; i++) {
		dent = semfs_direntryarray_get(semfs->semfs_dents, i);
		if (dent == NULL) {
			if (empty == num) {
				empty = i;
			}
			continue;
		}
		if (!strcmp(dent->semd_name, name)) {
			/* found */
			if (excl) {
				lock_release(semfs->semfs_dirlock);
				return EEXIST;
			}
			result = semfs_getvnode(semfs, dent->semd_semnum,
						resultvn);
			lock_release(semfs->semfs_dirlock);
			return result;
		}
	}

	/* create it */
	sem = semfs_sem_create(name);
	if (sem == NULL) {
		result = ENOMEM;
		goto fail_unlock;
	}
	lock_acquire(semfs->semfs_tablelock);
	result = semfs_sem_insert(semfs, sem, &semnum);
	lock_release(semfs->semfs_tablelock);
	if (result) {
		goto fail_uncreate;
	}

	dent = semfs_direntry_create(name, semnum);
	if (dent == NULL) {
		goto fail_uninsert;
	}

	if (empty < num) {
		semfs_direntryarray_set(semfs->semfs_dents, empty, dent);
	}
	else {
		result = semfs_direntryarray_add(semfs->semfs_dents, dent,
						 &empty);
		if (result) {
			goto fail_undent;
		}
	}

	result = semfs_getvnode(semfs, semnum, resultvn);
	if (result) {
		goto fail_undir;
	}

	sem->sems_linked = true;
	lock_release(semfs->semfs_dirlock);
	return 0;

 fail_undir:
	semfs_direntryarray_set(semfs->semfs_dents, empty, NULL);
 fail_undent:
	semfs_direntry_destroy(dent);
 fail_uninsert:
	lock_acquire(semfs->semfs_tablelock);
	semfs_semarray_set(semfs->semfs_sems, semnum, NULL);
	lock_release(semfs->semfs_tablelock);
 fail_uncreate:
	semfs_sem_destroy(sem);
 fail_unlock:
	lock_release(semfs->semfs_dirlock);
	return result;
}
Esempio n. 18
0
void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacket, LPVOID pPacketData, DWORD IncPacketSize) {
    CaptureJob *j;
    HANDLE pkt;
    unsigned char *pktbuf;
    unsigned char *pktmax;
    struct eth_hdr *eth;
    struct ip_hdr *ip;
    struct tcp_hdr *tcp;
//	struct udp_hdr *udp;

    j = (CaptureJob *)Param;
    pktbuf = (unsigned char *)pPacketData;
    pktmax = pktbuf + IncPacketSize;

    // Only process active jobs
    if(!j->active) return;

    // Traffic filtering goes here
    do {
        // Skip matching on short packets
        if(IncPacketSize < ETH_HDR_LEN + IP_HDR_LEN + TCP_HDR_LEN) {
            dprintf("sniffer>> skipping exclusion because the packet is too small");
            break;
        }

        // Match IP packets
        if(!peername4) {
            dprintf("sniffer>> skipping exclusion because peername4 is not defined");
            break;
        }

        // Skip non-IP packets
        eth = (struct eth_hdr *) pktbuf;
        if(ntohs(eth->eth_type) != ETH_TYPE_IP) {
            dprintf("sniffer>> skipping non-IP packet from filter");
            break;
        }

        // Skip non-TCP/UDP packets
        ip = (struct ip_hdr *) &pktbuf[ETH_HDR_LEN];
        if(ip->ip_p != IP_PROTO_TCP && ip->ip_p != IP_PROTO_UDP) {
            dprintf("sniffer>> skipping non-TCP/UDP packet from filter: %d", ip->ip_p);
            break;
        }

        if(ip->ip_p == IP_PROTO_TCP) {
            tcp = (struct tcp_hdr *) &pktbuf[ETH_HDR_LEN + (ip->ip_hl * 4)];
            if( (unsigned char *)tcp + TCP_HDR_LEN > pktmax) {
                dprintf("sniffer>> TCP packet is too short");
                break;
            }

            // Ignore our own control session's traffic
            if ( (memcmp(&ip->ip_src,  &peername4->sin_addr, 4) == 0 && tcp->th_sport == peername4->sin_port) ||
                    (memcmp(&ip->ip_dst, &peername4->sin_addr, 4) == 0 && tcp->th_dport == peername4->sin_port) ) {
                return;
            }
            // TODO: Scan through a list of included/excluded ports
        }

        // All done matching exclusions
    } while(0);

    // Thread-synchronized access to the queue

    //    -- PKS, per job locking would be finer grained.
    //       however, it probably doesn't matter.

    lock_acquire(snifferm);

    if(j->idx_pkts >= j->max_pkts) j->idx_pkts = 0;
    j->cur_pkts++;
    j->cur_bytes += IncPacketSize;

    pkt = PktCreate(j->mtu);
    PktCopyPacketToPacket(pkt, hPacket);
    if(j->pkts[j->idx_pkts])
        PktDestroy(j->pkts[j->idx_pkts]);
    j->pkts[j->idx_pkts] = pkt;
    j->idx_pkts++;

    lock_release(snifferm);
}
Esempio n. 19
0
void cmd_pipe_cb(int fd, short event, void *arg)
{
	struct jsonrpc_pipe_cmd *cmd;

	if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
		ERR("FATAL ERROR: failed to read from command pipe: %s\n",
				strerror(errno));
		return;
	}


	switch(cmd->type) {
	case CMD_CLOSE:
		if(cmd->server) {
			wait_close(cmd->server);
		}
		goto end;
		break;
	case CMD_RECONNECT:
		if(cmd->server) {
			wait_reconnect(cmd->server);
		}
		goto end;
		break;
	case CMD_CONNECT:
		if(cmd->server) {
			bev_connect(cmd->server);
		}
		goto end;
		break;
	case CMD_UPDATE_SERVER_GROUP:
		if(cmd->new_grp) {
			jsonrpc_server_group_t* old_grp = *global_server_group;
			*global_server_group = cmd->new_grp;
			free_server_group(&old_grp);
		}
		lock_release(jsonrpc_server_group_lock);
		goto end;
		break;

	case CMD_SEND:
		break;

	default:
		ERR("Unrecognized pipe command: %d\n", cmd->type);
		goto end;
		break;
	}

	/* command is SEND */

	jsonrpc_req_cmd_t* req_cmd = cmd->req_cmd;
	if(req_cmd == NULL) {
		ERR("req_cmd is NULL. Invalid send command\n");
		goto end;
	}

	jsonrpc_request_t* req = NULL;
	req = create_request(req_cmd);
	if (!req || !req->payload) {
		json_t* error = internal_error(JRPC_ERR_REQ_BUILD, NULL);
		pv_value_t val;
		char* freeme = NULL;
		jsontoval(&val, &freeme, error);
		if(req_cmd->route.len <=0 && send_to_script(&val, req_cmd)<0) {
			ERR("Failed to build request (method: %.*s, params: %.*s)\n",
					STR(req_cmd->method), STR(req_cmd->params));
		}
		if(freeme) free(freeme);
		if(error) json_decref(error);
		free_req_cmd(req_cmd);
		goto end;
	}

	int sent = jsonrpc_send(req_cmd->conn, req, req_cmd->notify_only);

	char* type;
	if (sent<0) {
		if (req_cmd->notify_only == false) {
			type = "Request";
		} else {
			type = "Notification";
		}
		WARN("%s could not be sent to connection group: %.*s\n",
				type, STR(req_cmd->conn));
		fail_request(JRPC_ERR_SEND, req, "Failed to send request");
	}

end:
	free_pipe_cmd(cmd);
}
Esempio n. 20
0
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) {
    Packet *response = packet_create_response(packet);
    unsigned int ifid, i;
    unsigned int bcnt;
    CaptureJob *j;
    DWORD result;

    check_pssdk();
    dprintf("sniffer>> capture_dump_read()");

    ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
    bcnt = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_BYTE_COUNT);
    bcnt = min(bcnt, 32*1024*1024);

    dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt);

    result = ERROR_SUCCESS;

    do {
        // the interface is invalid
        if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
            packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
            goto fail;
        }

        j = &open_captures[ifid];
        if(! j->dbuf) {
            packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
            goto fail;
        }

        if(j->didx + bcnt > j->dlen) {
            bcnt = j->dlen - j->didx;
        }

        packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt);
        packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf+j->didx, bcnt);
        j->didx += bcnt;
    } while(0);

    // Free memory if the read is complete
    if(j->didx >= j->dlen-1) {
        free(j->dbuf);
        j->dbuf = NULL;
        j->didx = 0;
        j->dlen = 0;
        // if dump occurs when interface is not active, i.e sniff has ended, release info
        if (j->active == 0) {
            dprintf("sniffer>> capture_dump_read, release CaptureJob");
            lock_acquire(snifferm);
            for(i=0; i<j->max_pkts; i++) {
                if(!j->pkts[i]) break;
                PktDestroy(j->pkts[i]);
                j->pkts[i] = NULL;
            }
            free(j->pkts);
            memset(j, 0, sizeof(CaptureJob));
            lock_release(snifferm);
        }
    }

fail:
    packet_transmit_response(result, remote, response);
    return ERROR_SUCCESS;
}
Esempio n. 21
0
int update_phtable(presentity_t* presentity, str pres_uri, str body)
{
	char* sphere= NULL;
	unsigned int hash_code;
	pres_entry_t* p;
	int ret= 0;
	str* xcap_doc= NULL;

	/* get new sphere */
	sphere= extract_sphere(body);
	if(sphere==NULL)
	{
		LM_DBG("no sphere defined in new body\n");
		return 0;
	}

	/* search for record in hash table */
	hash_code= core_hash(&pres_uri, NULL, phtable_size);
	
	lock_get(&pres_htable[hash_code].lock);

	p= search_phtable(&pres_uri, presentity->event->evp->type, hash_code);
	if(p== NULL)
	{
		lock_release(&pres_htable[hash_code].lock);
		goto done;
	}
	
	if(p->sphere)
	{
		if(strcmp(p->sphere, sphere)!= 0)
		{
			/* new sphere definition */
			shm_free(p->sphere);
		}
		else
		{
			/* no change in sphere definition */
			lock_release(&pres_htable[hash_code].lock);
			pkg_free(sphere);
			return 0;
		}
	
	}


	p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char));
	if(p->sphere== NULL)
	{
		lock_release(&pres_htable[hash_code].lock);
		ret= -1;
		goto done;
	}
	strcpy(p->sphere, sphere);
		
	lock_release(&pres_htable[hash_code].lock);

	/* call for watchers status update */

	if(presentity->event->get_rules_doc(&presentity->user, &presentity->domain,
				&xcap_doc)< 0)
	{
		LM_ERR("failed to retreive xcap document\n");
		ret= -1;
		goto done;
	}

	update_watchers_status(pres_uri, presentity->event, xcap_doc);


done:

	if(xcap_doc)
	{
		if(xcap_doc->s)
			pkg_free(xcap_doc->s);
		pkg_free(xcap_doc);
	}

	if(sphere)
		pkg_free(sphere);
	return ret;
}
Esempio n. 22
0
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
    Packet *response = packet_create_response(packet);
    unsigned int ifid;
    unsigned int rbuf,mbuf;
    unsigned int *tmp;

    CaptureJob *j;
    DWORD result,pcnt,rcnt,i;
#ifdef _WIN64
    ULONGLONG thilo;
#endif
    DWORD thi, tlo;

    check_pssdk();
    dprintf("sniffer>> capture_dump()");

    ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
    dprintf("sniffer>> capture_dump(0x%.8x)", ifid);

    result = ERROR_SUCCESS;

    lock_acquire(snifferm);

    do {
        // the interface is invalid
        if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
            result = ERROR_INVALID_PARAMETER;
            break;
        }

        j = &open_captures[ifid];

        // the interface was not captured
#ifdef _WIN32
        if(! j->adp)
#else
        if(! j->pcap)
#endif
        {
            result = ERROR_INVALID_PARAMETER;
            break;
        }

        // Free any existing packet buffer
        if(j->dbuf) {
            free(j->dbuf);
            j->dbuf = NULL;
            j->dlen = 0;
            j->didx = 0;
        }

        // Add basic stats
        pcnt = 0;
        rcnt = 0;

        mbuf = (1024*1024);
        j->dbuf = malloc(mbuf);
        rbuf = 0;

        for(i=0; i<j->max_pkts; i++) {
            if(!j->pkts[i]) break;

            rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i]));
            if(mbuf < rbuf) {
                mbuf += (1024*1024);
                j->dbuf = realloc(j->dbuf, mbuf);

                if(!j->dbuf) {
                    dprintf("sniffer>> realloc of %d bytes failed!", rbuf);
                    result = ERROR_NOT_ENOUGH_MEMORY;
                    break;
                }
            }

            tmp = (unsigned int *)( j->dbuf + rcnt );
#ifdef _WIN64
            thilo = PktGetId(j->pkts[i]);
            thi = (DWORD)(thilo >> 32);
            tlo = (DWORD)(thilo & 0xFFFFFFFF);
#else
            tlo = PktGetId(j->pkts[i], &thi);
#endif
            *tmp = htonl(thi);
            tmp++;
            *tmp = htonl(tlo);
            tmp++;

#ifdef _WIN64
            thilo = PktGetTimeStamp(j->pkts[i]);
            thi = (DWORD)(thilo >> 32);
            tlo = (DWORD)(thilo & 0xFFFFFFFF);
#else
            tlo = PktGetTimeStamp(j->pkts[i], &thi);
#endif
            *tmp = htonl(thi);
            tmp++;
            *tmp = htonl(tlo);
            tmp++;

            tlo = PktGetPacketSize(j->pkts[i]);
            *tmp = htonl(tlo);
            tmp++;

            memcpy(j->dbuf+rcnt+20, PktGetPacketData(j->pkts[i]), tlo);

            rcnt += 20 + tlo;
            pcnt++;

            PktDestroy(j->pkts[i]);
            j->pkts[i] = NULL;
        }

        j->dlen = rcnt;

        packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt);
        packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt);
        // add capture datalink, needed when saving capture file, use TLV_TYPE_SNIFFER_INTERFACE_ID not to create a new TLV type
        packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_INTERFACE_ID, j->capture_linktype);

        dprintf("sniffer>> finished processing packets");

        j->cur_bytes = 0;
        j->cur_pkts  = 0;
        j->idx_pkts  = 0;
    } while(0);

    lock_release(snifferm);
    packet_transmit_response(result, remote, response);
    return ERROR_SUCCESS;
}
Esempio n. 23
0
dbt_table_p dbt_db_get_table(dbt_cache_p _dc, const str *_s)
{
	dbt_table_p _tbc = NULL;
	int hash;
	int hashidx;

	if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0) {
		LM_ERR("invalid parameter");
		return NULL;
	}

	hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
	hashidx = hash % DBT_CACHETBL_SIZE;
		
	lock_get(&_dbt_cachetbl[hashidx].sem);

	_tbc = _dbt_cachetbl[hashidx].dtp;

	while(_tbc)
	{
		if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len
				&& _tbc->name.len == _s->len
				&& !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len)
				&& !strncasecmp(_tbc->name.s, _s->s, _s->len))
		{
			/* found - if cache mode or no-change, return */
			if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1)
			{
				LM_DBG("cache or mtime succeeded for [%.*s]\n",
						_tbc->name.len, _tbc->name.s);
				return _tbc;
			}
			break;
		}
		_tbc = _tbc->next;
	}
	
	/* new table */
	if(_tbc) /* free old one */
	{
		dbt_db_del_table(_dc, _s, 0);
	}

	_tbc = dbt_load_file(_s, &(_dc->name));

	if(!_tbc)
	{
		LM_ERR("could not load database from file [%.*s]", _s->len, _s->s);
		lock_release(&_dbt_cachetbl[hashidx].sem);
		return NULL;
	}

	_tbc->hash = hash;
	_tbc->next = _dbt_cachetbl[hashidx].dtp;
	if(_dbt_cachetbl[hashidx].dtp)
		_dbt_cachetbl[hashidx].dtp->prev = _tbc;
	
	_dbt_cachetbl[hashidx].dtp = _tbc;

	/* table is locked */
	return _tbc;
}
Esempio n. 24
0
int sys_read(int fd, userptr_t buf, int len, int* retval)
{
	// argument checks.

	if(fd <0 || fd>= OPEN_MAX)
		return EBADF;
	
	int result;
	char kern_buffer[len + 1];

	// are we using this properly?.. check jinghao's blog for example
	// no actual use for the kern buffer, just doing this to check if memory location is valid.

	if(buf!= NULL)
	{
		result = copyin(buf, kern_buffer, len); // using this because users are stupid/malicious and can pass invalid memory addresses to the kernel.
	
		if(result)
		{
			kprintf("read copy in bad \n");
			return result;

		}
	}

	struct file_handle* fh = get_file_handle(curproc->t_file_table, fd);
	
	if(fh == NULL)
		return EBADF;

	if(!can_read(fh->openflags)) // could have other flags Or'd with O_RDONLY, need to change this.
		return EBADF;
	

// !!!! Should we do copyin's to kernel space, or will the VOP_WRITE take care of the invalid address issue for us.

	lock_acquire(fh->fh_lock); // IS this really necessary??.. turns out it is , offset should be synchronized. imagine if parent and child call this at the same time.
	struct iovec iov;
	struct uio u;

	iov.iov_ubase = (userptr_t)buf;
	iov.iov_len = len;		 // length of the memory space
	u.uio_iov = &iov;
	u.uio_iovcnt = 1;
	u.uio_resid = len;          // amount to read from the file
	u.uio_offset = fh->offset;
	u.uio_segflg =  UIO_USERSPACE;
	u.uio_rw = UIO_READ;
	u.uio_space = proc_getas(); // lifted from loadelf.c, is this the right way to do it?

	result = VOP_READ(fh->file, &u);
	if (result) {
		lock_release(fh->fh_lock);
		return result;
	}

	if (u.uio_resid != 0) {
//		kprintf("ELF: short read on segment - file truncated?\n");
	}

	// should update offset in the file handle.use lock. uio_offset will be updated. can use it directly.
	fh->offset = u.uio_offset;

	lock_release(fh->fh_lock);

	*retval = len - u.uio_resid; // number of bytes gets returned to the user
	return 0; 


}
Esempio n. 25
0
static struct mi_root* mi_cc_list_flows(struct mi_root *cmd, void *param)
{
	struct cc_flow *flow;
	struct mi_root *rpl_tree;
	struct mi_node *node;
	struct mi_node *rpl;
	struct mi_attr *attr;
	int len;
	char *p;

	rpl_tree = init_mi_tree( 200, MI_SSTR("OK") );
	if ( rpl_tree==NULL)
		return NULL;
	rpl = &rpl_tree->node;
	rpl->flags |= MI_IS_ARRAY;

	/* block access to data */
	lock_get( data->lock );

	for( flow=data->flows; flow ; flow=flow->next ) {

		node = add_mi_node_child( rpl, MI_DUP_VALUE, MI_SSTR("Flow"),
				flow->id.s, flow->id.len );
		if (node==NULL)
				goto error;

		p = int2str( (unsigned long)(flow->avg_call_duration), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Avg Call Duration"), p, len);
		if (attr==NULL)
				goto error;

		p = int2str( (unsigned long)(flow->processed_calls), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Processed Calls"), p, len);
		if (attr==NULL)
				goto error;

		p = int2str( (unsigned long)(flow->logged_agents), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Logged Agents"), p, len);
		if (attr==NULL)
				goto error;

		p = int2str( (unsigned long)(flow->ongoing_calls), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ongoing Calls"), p, len);
		if (attr==NULL)
				goto error;

		p = int2str( (unsigned long)(flow->ref_cnt), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ref"), p, len);
		if (attr==NULL)
				goto error;

	}

	lock_release( data->lock );

	return rpl_tree;

error:
	lock_release( data->lock );
	return 0;
}
Esempio n. 26
0
/**
 * run keep-alive list
 *
 */
int dlg_ka_run(ticks_t ti)
{
	dlg_ka_t *dka;
	dlg_cell_t *dlg;

	if(dlg_ka_interval<=0)
		return 0;

	while(1) {
		/* get head item */
		lock_get(dlg_ka_list_lock);
		if(*dlg_ka_list_head==NULL) {
			lock_release(dlg_ka_list_lock);
			return 0;
		}
		dka = *dlg_ka_list_head;
#if 0
		LM_DBG("dlg ka timer at %lu for"
				" dlg[%u,%u] on %lu\n", (unsigned long)ti,
				dka->iuid.h_entry, dka->iuid.h_id,
				(unsigned long)dka->katime);
#endif
		if(dka->katime>ti) {
			lock_release(dlg_ka_list_lock);
			return 0;
		}
		if(*dlg_ka_list_head == *dlg_ka_list_tail) {
			*dlg_ka_list_head = NULL;
			*dlg_ka_list_tail = NULL;
		} else {
			*dlg_ka_list_head = dka->next;
		}
		lock_release(dlg_ka_list_lock);

		/* send keep-alive for dka */
		dlg = dlg_get_by_iuid(&dka->iuid);
		if(dlg==NULL) {
			shm_free(dka);
			dka = NULL;
		} else {
			if((dka->iflags & DLG_IFLAG_KA_SRC)
					&& (dlg->state==DLG_STATE_CONFIRMED))
				dlg_send_ka(dlg, DLG_CALLER_LEG);
			if((dka->iflags & DLG_IFLAG_KA_DST)
					&& (dlg->state==DLG_STATE_CONFIRMED))
				dlg_send_ka(dlg, DLG_CALLEE_LEG);
			if(dlg->state==DLG_STATE_DELETED) {
				shm_free(dka);
				dka = NULL;
			}
			dlg_release(dlg);
		}
		/* append to tail */
		if(dka!=NULL)
		{
			dka->katime = ti + dlg_ka_interval;
			lock_get(dlg_ka_list_lock);
			if(*dlg_ka_list_tail!=NULL)
				(*dlg_ka_list_tail)->next = dka;
			if(*dlg_ka_list_head==NULL)
				*dlg_ka_list_head = dka;
			*dlg_ka_list_tail = dka;
			lock_release(dlg_ka_list_lock);
		}
	}

	return 0;
}
Esempio n. 27
0
static struct mi_root* mi_cc_list_calls(struct mi_root *cmd_tree, void *param)
{
	struct cc_call *call;
	struct cc_agent *agent;
	struct mi_root *rpl_tree;
	struct mi_node *node;
	struct mi_node *rpl;
	struct mi_attr *attr;
	char *p;
	int len;
	static str call_state[12]= {{"none", 4},
			{"welcome", 7},
			{"queued", 6},
			{"toagent", 7},
			{"ended", 5}};

	rpl_tree = init_mi_tree( 200, MI_SSTR("OK") );
	if ( rpl_tree==NULL)
		return NULL;
	rpl = &rpl_tree->node;
	rpl->flags |= MI_IS_ARRAY;

	/* block access to data */
	lock_get( data->lock );

	for( call=data->list.first ; call ; call=call->next_list ) {

		node = add_mi_node_child( rpl, MI_DUP_VALUE, "Call", 4,
				call->b2bua_id.s, call->b2bua_id.len);
		if (node==NULL)
				goto error;

		p = int2str( (unsigned long)(call->ref_cnt), &len);
		attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Ref"), p, len);
		if (attr==NULL)
				goto error;
		if(call->ign_cback)
			attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("State"), MI_SSTR("ignored"));
		else
			attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("State"), call_state[call->state].s, call_state[call->state].len);
		if (attr==NULL)
				goto error;

		LM_DBG("call->recv_time= %d, ticks= %d\n", call->recv_time, get_ticks());
		if(call->state != CC_CALL_ENDED)
		{
			p = int2str( (unsigned long)(call->recv_time?(get_ticks() - call->recv_time):0), &len);
			attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Call Time"), p, len);
			if (attr==NULL)
				goto error;

			if(call->flow) {
				attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Flow"), call->flow->id.s, call->flow->id.len);
				if (attr==NULL)
					goto error;
			}
		}
		if(call->agent) {
				agent = call->agent;
				attr = add_mi_attr( node, MI_DUP_VALUE, MI_SSTR("Agent"), agent->id.s, agent->id.len);
				if (attr==NULL)
					goto error;	
		}

	}
	
	lock_release( data->lock );

	return rpl_tree;

error:
	lock_release( data->lock );
	return 0;
}
Esempio n. 28
0
void b2b_logic_dump(int no_lock)
{
	b2bl_tuple_t* tuple;
	int i;
	int n_insert_cols;

	if(b2bl_dbf.use_table(b2bl_db, &b2bl_dbtable)< 0)
	{
		LM_ERR("sql use table failed\n");
		return;
	}

	for(i = 0; i< b2bl_hsize; i++)
	{
		if(!no_lock)
			lock_get(&b2bl_htable[i].lock);
		tuple = b2bl_htable[i].first;
		while(tuple)
		{
			/* check the state of the scenario instantiation */
			if(tuple->db_flag == NO_UPDATEDB_FLAG)
				goto next;

			if(tuple->key == NULL)
			{
				LM_ERR("No key stored\n");
				goto next;
			}
			if(tuple->bridge_entities[0]==NULL || tuple->bridge_entities[1]== NULL)
			{
				LM_ERR("Bridge entities is NULL\n");
				if(tuple->bridge_entities[0]==NULL)
					LM_DBG("0 NULL\n");
				else
					LM_DBG("1 NULL\n");
				goto next;
			}

			qvals[0].val.str_val = *tuple->key;
			if(tuple->db_flag == INSERTDB_FLAG)
			{
				if(tuple->scenario)
					qvals[1].val.str_val = tuple->scenario->id;
				else{
					qvals[1].val.str_val.len = 0;
					qvals[1].val.str_val.s = "";
				}

				qvals[2].val.str_val = tuple->scenario_params[0];
				qvals[3].val.str_val = tuple->scenario_params[1];
				qvals[4].val.str_val = tuple->scenario_params[2];
				qvals[5].val.str_val = tuple->scenario_params[3];
				qvals[6].val.str_val = tuple->scenario_params[4];
				qvals[7].val.str_val = tuple->sdp;
			}


			qvals[8].val.int_val  = tuple->scenario_state;
			qvals[9].val.int_val  = tuple->next_scenario_state;
			qvals[10].val.int_val = tuple->lifetime - get_ticks() + (int)time(NULL);
			qvals[11].val.int_val = tuple->bridge_entities[0]->type;
			qvals[12].val.str_val = tuple->bridge_entities[0]->scenario_id;
			qvals[13].val.str_val = tuple->bridge_entities[0]->to_uri;
			qvals[14].val.str_val = tuple->bridge_entities[0]->from_uri;
			qvals[15].val.str_val = tuple->bridge_entities[0]->key;
			qvals[16].val.int_val = tuple->bridge_entities[1]->type;
			qvals[17].val.str_val = tuple->bridge_entities[1]->scenario_id;
			qvals[18].val.str_val = tuple->bridge_entities[1]->to_uri;
			qvals[19].val.str_val = tuple->bridge_entities[1]->from_uri;
			qvals[20].val.str_val = tuple->bridge_entities[1]->key;

			n_insert_cols = 21;

			if(tuple->bridge_entities[2])
			{
				qvals[21].val.int_val = tuple->bridge_entities[2]->type;
				qvals[22].val.str_val = tuple->bridge_entities[2]->scenario_id;
				qvals[23].val.str_val = tuple->bridge_entities[2]->to_uri;
				qvals[24].val.str_val = tuple->bridge_entities[2]->from_uri;
				qvals[25].val.str_val = tuple->bridge_entities[2]->key;
			}
			n_insert_cols = DB_COLS_NO;

			/* insert into database */
			if(tuple->db_flag == INSERTDB_FLAG)
			{
				if(b2bl_dbf.insert(b2bl_db, qcols, qvals, n_insert_cols)< 0)
				{
					LM_ERR("Sql insert failed\n");
					if(!no_lock)
						lock_release(&b2bl_htable[i].lock);
					return;
				}
			}
			else
			{
				/*do update */
				if(b2bl_dbf.update(b2bl_db, qcols, 0, qvals, qcols+n_query_update,
					qvals+n_query_update, 1, DB_COLS_NO - n_query_update)< 0)
				{
					LM_ERR("Sql update failed\n");
					if(!no_lock)
						lock_release(&b2bl_htable[i].lock);
					return;
				}
			}
			tuple->db_flag = NO_UPDATEDB_FLAG;
next:
			tuple = tuple->next;
		}
		if(!no_lock)
			lock_release(&b2bl_htable[i].lock);
	}
}
Esempio n. 29
0
static void terminate_call(struct cc_call *call, b2bl_dlg_stat_t* stat,
		call_state prev_state)
{
	str un, fid, aid;
	int type;

	if(prev_state == CC_CALL_ENDED) {
		LM_CRIT("BUG - terminate state \n");
		return;
	}
	
	LM_DBG("terminating call %p (stat=%p)\n",call,stat);

	lock_get( data->lock );

	prepare_cdr( call, &un, &fid , &aid);

	if (prev_state==CC_CALL_TOAGENT) {
		/* free the agent */
		if (stat && stat->call_time && prev_state==CC_CALL_TOAGENT) {
			call->agent->state = CC_AGENT_WRAPUP;
			call->agent->last_call_end = get_ticks();
			call->flow->processed_calls ++;
			call->flow->avg_call_duration =
				( ((float)stat->call_time + 
				((float)call->flow->avg_call_duration *
				(call->flow->processed_calls-1)) ) ) /
				call->flow->processed_calls ;
			/* update awt for established calls */
			update_awt( stat->start_time - call->recv_time );
			update_cc_flow_awt(call->flow, stat->start_time - call->recv_time);
			update_cc_agent_att(call->agent, stat->call_time);
		} else {
			call->agent->state = CC_AGENT_FREE;
			/* update awt for failed calls */
			update_awt( get_ticks() - call->recv_time );
			update_cc_flow_awt( call->flow, get_ticks() - call->recv_time );
		}
		/* update last_call_end for agent */
		cc_db_update_agent_end_call(call->agent);
		call->agent->ref_cnt--;
		call->agent = NULL;
	} else {
		/* update awt for failed calls */
		update_awt( get_ticks() - call->recv_time );
		update_cc_flow_awt( call->flow, get_ticks() - call->recv_time );
	}

	/* remove the call from queue (if there) */
	if ( is_call_in_queue(data, call) ) {
		cc_queue_rmv_call( data, call);
		call->ref_cnt--;
	}

	call->flow->ongoing_calls--;

	lock_release( data->lock );

	if (call->setup_time==-1 && stat)
		call->setup_time = stat->setup_time;

	/* generate CDR */
	type = (stat==NULL) ? -1 : ((prev_state==CC_CALL_TOAGENT && stat->call_time)? 0 : 1);
	cc_write_cdr( &un, &fid, &aid, type, call->recv_time,
		((type==0)? stat->start_time : get_ticks()) - call->recv_time ,
		(type==0)?stat->call_time:0 , call->setup_time, call->no_rejections, call->fst_flags,
		call->id);

	cc_db_delete_call(call);
}
Esempio n. 30
0
dbt_table_p dbt_db_get_table(dbt_cache_p _dc, str *_s)
{
	dbt_table_p _tbc = NULL;
	int hash;
	int hashidx;

	if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0)
		return NULL;

	hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
	hashidx = hash % DBT_CACHETBL_SIZE;
		
	lock_get(&_dbt_cachetbl[hashidx].sem);

	_tbc = _dbt_cachetbl[hashidx].dtp;

	while(_tbc)
	{
		if(_tbc->hash==hash && _tbc->dbname.len == _dc->name.len
				&& _tbc->name.len == _s->len
				&& !strncasecmp(_tbc->dbname.s, _dc->name.s, _dc->name.len)
				&& !strncasecmp(_tbc->name.s, _s->s, _s->len))
		{
			/* found - if cache mode or no-change, return */
			if(db_mode==0 || dbt_check_mtime(_s, &(_dc->name), &(_tbc->mt))!=1)
			{
				LM_DBG("cache or mtime succeeded\n");
				return _tbc;
			}
			break;
		}
		_tbc = _tbc->next;
	}
	
	/* new table */
	if(_tbc) /* free old one */
	{
		lock_release(&_dbt_cachetbl[hashidx].sem);
		dbt_db_del_table(_dc, _s);
		lock_get(&_dbt_cachetbl[hashidx].sem);
	}

	_tbc = dbt_load_file(_s, &(_dc->name));

#ifdef DBT_EXTRA_DEBUG
	LM_DBG("%.*s\n", _s->len, _s->s);
	dbt_print_table(_tbc, NULL);
#endif

	if(!_tbc)
	{
		lock_release(&_dbt_cachetbl[hashidx].sem);
		return NULL;
	}

	_tbc->hash = hash;
	_tbc->next = _dbt_cachetbl[hashidx].dtp;
	if(_dbt_cachetbl[hashidx].dtp)
		_dbt_cachetbl[hashidx].dtp->prev = _tbc;
	
	_dbt_cachetbl[hashidx].dtp = _tbc;

	/* table is locked */
	return _tbc;
}