Beispiel #1
0
/*!
 * \brief Get the size of a profile
 * \param profile evaluated profile
 * \param value value
 * \return the profile size
 */
unsigned int get_profile_size(struct dlg_profile_table *profile, str *value)
{
	unsigned int n,i;
	struct dlg_profile_hash *ph;

	if (profile->has_value==0 || value==NULL) {
		/* iterate through the hash and count all records */
		lock_get( &profile->lock );
		for( i=0,n=0 ; i<profile->size ; i++ )
			n += profile->entries[i].content;
		lock_release( &profile->lock );
		return n;
	} else {
		/* iterate through the hash entry and count only matching */
		/* calculate the hash position */
		i = calc_hash_profile( value, NULL, profile);
		n = 0;
		lock_get( &profile->lock );
		ph = profile->entries[i].first;
		if(ph) {
			do {
				/* compare */
				if ( value->len==ph->value.len &&
				memcmp(value->s,ph->value.s,value->len)==0 ) {
					/* found */
					n++;
				}
				/* next */
				ph=ph->next;
			}while( ph!=profile->entries[i].first );
		}
		lock_release( &profile->lock );
		return n;
	}
}
Beispiel #2
0
/*!
 * \brief Link a dialog profile
 * \param linker dialog linker
 * \param dlg dialog cell
 */
static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *dlg)
{
	unsigned int hash;
	struct dlg_profile_entry *p_entry;
	struct dlg_entry *d_entry;

	/* add the linker to the dialog */
	/* FIXME zero h_id is not 100% for testing if the dialog is inserted
	 * into the hash table -> we need circular lists  -bogdan */
	if (dlg->h_id) {
		d_entry = &d_table->entries[dlg->h_entry];
		dlg_lock( d_table, d_entry);
		linker->next = dlg->profile_links;
		dlg->profile_links =linker;
		linker->hash_linker.dlg = dlg;
		dlg_unlock( d_table, d_entry);
	} else {
		linker->next = dlg->profile_links;
		dlg->profile_links =linker;
		linker->hash_linker.dlg = dlg;
	}

	/* calculate the hash position */
	hash = calc_hash_profile(&linker->hash_linker.value, dlg, linker->profile);
	linker->hash_linker.hash = hash;

	/* insert into profile hash table */
	p_entry = &linker->profile->entries[hash];
	lock_get( &linker->profile->lock );
	if (p_entry->first) {
		linker->hash_linker.prev = p_entry->first->prev;
		linker->hash_linker.next = p_entry->first;
		p_entry->first->prev->next = &linker->hash_linker;
		p_entry->first->prev = &linker->hash_linker;
	} else {
		p_entry->first = linker->hash_linker.next 
			= linker->hash_linker.prev = &linker->hash_linker;
	}
	p_entry->content ++;
	lock_release( &linker->profile->lock );
}
Beispiel #3
0
/*!
 * \brief Remove profile
 * \param profile pointer to profile
 * \param value profile value
 * \param puid profile unique id
 */
int remove_profile(dlg_profile_table_t *profile, str *value, str *puid)
{
	unsigned int hash;
	struct dlg_profile_entry *p_entry;
	struct dlg_profile_hash *lh;

	hash = calc_hash_profile(value, puid, profile);
	lock_get(&profile->lock );
	p_entry = &profile->entries[hash];
	lh = p_entry->first;
	if(lh) {
		do {
			if(lh->dlg==NULL && lh->puid_len==puid->len
					&& lh->value.len==value->len
					&& strncmp(lh->puid, puid->s, puid->len)==0
					&& strncmp(lh->value.s, value->s, value->len)==0) {
				/* last element on the list? */
				if (lh==lh->next) {
					p_entry->first = NULL;
				} else {
					if (p_entry->first==lh)
						p_entry->first = lh->next;
					lh->next->prev = lh->prev;
					lh->prev->next = lh->next;
				}
				lh->next = lh->prev = NULL;
				if(lh->linker) shm_free(lh->linker);
				p_entry->content--;
				lock_release(&profile->lock );
				return 1;
			}
			lh = lh->next;
		} while(lh != p_entry->first);
	}
	lock_release(&profile->lock );
	return 0;
}
Beispiel #4
0
/*!
 * \brief Link a dialog profile
 * \param linker dialog linker
 * \param vkey key for profile hash table
 */
static void link_profile(struct dlg_profile_link *linker, str *vkey)
{
	unsigned int hash;
	struct dlg_profile_entry *p_entry;

	/* calculate the hash position */
	hash = calc_hash_profile(&linker->hash_linker.value, vkey, linker->profile);
	linker->hash_linker.hash = hash;

	/* insert into profile hash table */
	p_entry = &linker->profile->entries[hash];
	lock_get( &linker->profile->lock );
	if (p_entry->first) {
		linker->hash_linker.prev = p_entry->first->prev;
		linker->hash_linker.next = p_entry->first;
		p_entry->first->prev->next = &linker->hash_linker;
		p_entry->first->prev = &linker->hash_linker;
	} else {
		p_entry->first = linker->hash_linker.next 
			= linker->hash_linker.prev = &linker->hash_linker;
	}
	p_entry->content ++;
	lock_release( &linker->profile->lock );
}
Beispiel #5
0
int	dlg_set_timeout_by_profile(struct dlg_profile_table *profile, 
				   str *value, int timeout) 
{
	unsigned int		i = 0;
	dlg_cell_t		*this_dlg = NULL;
	struct dlg_profile_hash	*ph = NULL;

	/* Private structure necessary for manipulating dialog 
         * timeouts outside of profile locks.  Admittedly, an
         * ugly hack, but avoids some concurrency issues.
         */

	struct dlg_map_list {
		unsigned int		h_id;
		unsigned int		h_entry;
		struct dlg_map_list	*next;
	} *map_head, *map_scan, *map_scan_next;

	map_head = NULL;

	/* If the profile has no value, iterate through every 
	 * node and set its timeout.
	 */

	if(profile->has_value == 0 || value == NULL) {
		lock_get(&profile->lock);

		for(i = 0; i < profile->size; i ++) {
			ph = profile->entries[i].first;

			if(!ph) continue;
			
			do { 
				struct dlg_map_list *d = malloc(sizeof(struct dlg_map_list));

				if(!d)
					return -1;

				memset(d, 0, sizeof(struct dlg_map_list));

				d->h_id = ph->dlg->h_id;
				d->h_entry = ph->dlg->h_entry;

				if(map_head == NULL)
					map_head = d;
				else {
					d->next = map_head;
					map_head = d;
				}
	
				ph = ph->next;
			} while(ph != profile->entries[i].first);
		} 

		lock_release(&profile->lock);
	}

	else {
		i = calc_hash_profile(value, NULL, profile);

		lock_get(&profile->lock);

		ph = profile->entries[i].first;

		if(ph) {
			do {
				if(ph && value->len == ph->value.len &&
				   memcmp(value->s, ph->value.s, value->len) == 0) {
					struct dlg_map_list *d = malloc(sizeof(struct dlg_map_list));

					if(!d)
						return -1;

					memset(d, 0, sizeof(struct dlg_map_list));

					d->h_id = ph->dlg->h_id;
					d->h_entry = ph->dlg->h_entry;

					if(map_head == NULL)
						map_head = d;
					else {
						d->next = map_head;
						map_head = d;
					}
				}

				ph = ph->next;
			} while(ph && ph != profile->entries[i].first);
		}

		lock_release(&profile->lock);
	}

	/* Walk the list and bulk-set the timeout */
	
	for(map_scan = map_head; map_scan != NULL; map_scan = map_scan_next) {
		map_scan_next = map_scan->next;

		this_dlg = dlg_lookup(map_scan->h_entry, map_scan->h_id);

		if(!this_dlg) {
			LM_CRIT("Unable to find dialog %d:%d\n", map_scan->h_entry, map_scan->h_id);
		} else if(this_dlg->state >= DLG_STATE_EARLY) {	
			if(update_dlg_timeout(this_dlg, timeout) < 0) {
               			LM_ERR("Unable to set timeout on %d:%d\n", map_scan->h_entry,
					map_scan->h_id);
			}

	                dlg_release(this_dlg);
		}

		free(map_scan);
	}

	return 0;
}