예제 #1
0
파일: ot_nonce.c 프로젝트: 4N7HR4X/kamailio
/* check if nonce w/ index i is expected/valid and if so marked it "seen"
 * returns: 0 - ok, < 0 some error:
 * OTN_INV_POOL      (pool number is invalid/corrupted)
 * OTN_ID_OVERFLOW   (crt_id has overflowed with partition size since the
 *                    id was generated)
 * OTN_REPLAY        (nonce id seen before => replay )
 */
enum otn_check_ret otn_check_id(nid_t id, unsigned pool)
{
	unsigned int i;
	unsigned n, b;
	otn_cell_t v, b_mask;

	if (unlikely(pool>=nid_pool_no))
		return OTN_INV_POOL;
	if (unlikely(otn_id_check_overflow(id, pool)))
		return OTN_ID_OVERFLOW;
	n=get_otn_array_bit_idx(id, pool); /* n-th bit */
	i=get_otn_array_cell_idx(n);    /* aray index i, corresponding to n */
	b=get_otn_cell_bit(n);          /* bit pos corresponding to n */
	b_mask= (otn_cell_t)1<<b;

#ifdef OTN_CELL_T_LONG
	v=atomic_get_long(&oth_array[i]);
	if (unlikely(v & b_mask))
		return OTN_REPLAY;
	atomic_or_long((long*)&otn_array[i],  b_mask);
#else
	v=atomic_get_int(&otn_array[i]);
	if (unlikely(v & b_mask))
		return OTN_REPLAY;
	atomic_or_int((int*)&otn_array[i],  b_mask);
#endif /* OTN_CELL_T_LONG */
	return 0;
}
예제 #2
0
/*!
 * \brief Unset a dialog profile
 * \param msg SIP message
 * \param value value
 * \param profile dialog profile table
 * \return 1 on success, -1 on failure
 */
int unset_dlg_profile(sip_msg_t *msg, str *value,
		dlg_profile_table_t *profile)
{
	dlg_cell_t *dlg;
	dlg_profile_link_t *linker;
	dlg_profile_link_t *linker_prev;
	dlg_entry_t *d_entry;

	if (is_route_type(REQUEST_ROUTE)) {
		LM_ERR("dialog delete profile cannot be used in request route\n");
		return -1;
	}

	/* get current dialog */
	dlg = dlg_get_msg_dialog(msg);

	if (dlg==NULL) {
		LM_WARN("dialog is NULL for delete profile\n");
		return -1;
	}

	/* check the dialog linkers */
	d_entry = &d_table->entries[dlg->h_entry];
	dlg_lock( d_table, d_entry);
	linker = dlg->profile_links;
	linker_prev = NULL;
	for( ; linker ; linker_prev=linker,linker=linker->next) {
		if (linker->profile==profile) {
			if (profile->has_value==0) {
				goto found;
			} else if (value && value->len==linker->hash_linker.value.len &&
			memcmp(value->s,linker->hash_linker.value.s,value->len)==0){
				goto found;
			}
			/* allow further search - maybe the dialog is inserted twice in
			 * the same profile, but with different values -bogdan
			 */
		}
	}
	atomic_or_int((volatile int*)&dlg->dflags, DLG_FLAG_CHANGED_PROF);
	dlg_unlock( d_table, d_entry);
	dlg_release(dlg);
	return -1;

found:
	/* table still locked */
	/* remove the linker element from dialog */
	if (linker_prev==NULL) {
		dlg->profile_links = linker->next;
	} else {
		linker_prev->next = linker->next;
	}
	linker->next = NULL;
	dlg_unlock( d_table, d_entry);
	/* remove linker from profile table and free it */
	destroy_linkers(linker);
	dlg_release(dlg);
	return 1;
}
예제 #3
0
/* lockless insert: should be always safe */
int insert_tmcb(struct tmcb_head_list *cb_list, int types,
				transaction_cb f, void *param,
				release_tmcb_param rel_func)
{
	struct tm_callback *cbp;
	struct tm_callback *old;


	/* build a new callback structure */
	if (!(cbp=shm_malloc( sizeof( struct tm_callback)))) {
		LOG(L_ERR, "ERROR:tm:insert_tmcb: out of shm. mem\n");
		return E_OUT_OF_MEM;
	}

	atomic_or_int(&cb_list->reg_types, types);
	/* ... and fill it up */
	cbp->callback = f;
	cbp->param = param;
	cbp->release = rel_func;
	cbp->types = types;
	cbp->id=0;
	old=(struct tm_callback*)cb_list->first;
	/* link it into the proper place... */
	do{
		cbp->next = old;
		/*
		if (cbp->next)
			cbp->id = cbp->next->id+1;
		else
			cbp->id = 0;
		 -- callback ids are useless -- andrei */
		membar_write_atomic_op();
		old=(void*)atomic_cmpxchg_long((void*)&cb_list->first,
										(long)old, (long)cbp);
	}while(old!=cbp->next);

	return 1;
}
예제 #4
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)
{
	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;
	}

	atomic_or_int((volatile int*)&dlg->dflags, DLG_FLAG_CHANGED_PROF);
	link_profile(linker, &dlg->callid);
}