Пример #1
0
int update_subscriber(impurecord_t* urec, reg_subscriber** _reg_subscriber, int *expires, int *local_cseq, int *version) {

    subs_t subs;
    unsigned int hash_code = 0;
    reg_subscriber *rs = *_reg_subscriber;
    if (expires) {
        rs->expires = *expires;
    } else {
        LM_DBG("No expires so will not update subscriber expires.\n");
    }
    if (local_cseq) {
        rs->local_cseq = *local_cseq;
    } else {
        LM_DBG("No local cseq so will not update subscriber local cseq.\n");
    }
    if (version) {
        rs->version = *version;
    } else {
        LM_DBG("No version so will not update subscriber version.\n");
    }
    
    /*This lets us get presentity URI info for subsequent SUBSCRIBEs that don't have presentity URI as req URI*/
    get_act_time();
    
    subs.pres_uri = rs->presentity_uri;
    subs.from_tag = rs->from_tag;
    subs.to_tag = rs->to_tag;
    subs.callid = rs->call_id;
    subs.expires = rs->expires - act_time;
    subs.contact = rs->watcher_contact;
    
    hash_code = core_hash(&subs.callid, &subs.to_tag, sub_dialog_hash_size);
    
    LM_DBG("Updating sub dialog hash info with call_id: <%.*s> and ttag <%.*s> amd ftag <%.*s> and hash code <%d>", subs.callid.len, subs.callid.s, subs.to_tag.len, subs.to_tag.s, subs.from_tag.len,  subs.from_tag.s, hash_code);
    
    if (pres_update_shtable(sub_dialog_table, hash_code, &subs, REMOTE_TYPE))
    {
	LM_ERR("while updating new subscription\n");
	return 0;
    }
        
    /*DB?*/
    if (db_mode == WRITE_THROUGH && db_insert_subscriber(urec, rs) != 0) {
	    LM_ERR("Failed to insert subscriber into DB subscriber [%.*s] to IMPU [%.*s]...continuing but db will be out of sync!\n", 
		    rs->presentity_uri.len, rs->presentity_uri.s, urec->public_identity.len, urec->public_identity.s);
    }

    return 1;
}
Пример #2
0
int get_hash_index_and_shared_line(struct sip_msg* msg, unsigned int *hash_index, str **shared_line)
{
	if(shared_line_spec_param.s)
	{
		memset(&shared_line_tok, 0, sizeof(pv_value_t));
		if(pv_get_spec_value(msg, &shared_line_spec, &shared_line_tok) < 0)
		{
			LM_ERR("Failed to get shared_line value\n");
			return -1;
		}
		//LM_DBG("got shared_line_spec_param flags [%d]\n", shared_line_tok.flags);
		if(!(shared_line_tok.flags&PV_VAL_INT) && (shared_line_tok.flags&PV_VAL_STR))
		{
			*shared_line = &shared_line_tok.rs;
			*hash_index = core_hash(&shared_line_tok.rs, NULL, b2b_sca_hsize);
			//LM_DBG("got hash_index=[%d] for PV_SPEC user [%.*s]\n", *hash_index,
			//	shared_line_tok.rs.len, shared_line_tok.rs.s);
			return 0;
		}
		else
		{
			LM_ERR("No shared line PV [%.*s] defined\n",
				shared_line_spec_param.len, shared_line_spec_param.s);
			return -1;
		}
	}
	else
	{
		LM_ERR("No shared line PV defined\n");
		return -1;
	}

	/* If the shared_line_spec_param is not set, use the username from original RURI */
	/*
	parse_orig_ruri(msg);
	if (msg->parsed_orig_ruri_ok &&
		msg->parsed_orig_ruri.user.s && msg->parsed_orig_ruri.user.len) {
		*shared_line = &msg->parsed_orig_ruri.user;
		*hash_index = core_hash(&msg->parsed_orig_ruri.user, NULL, b2b_sca_hsize);
		//LM_DBG("got hash_index=[%d] for RURI user [%.*s]\n", *hash_index,
		//		msg->parsed_orig_ruri.user.len, msg->parsed_orig_ruri.user.s);
		return 0;
	} else {
		LM_ERR("msg->parsed_orig_ruri_ok is NULL\n");
	}
	*/

	return -1;
}
Пример #3
0
int dbt_release_table(dbt_cache_p _dc, const str *_s)
{
	int hash;
	int hashidx;

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

	hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
	hashidx = hash % DBT_CACHETBL_SIZE;

	lock_release(&_dbt_cachetbl[hashidx].sem);

	return 0;
}
Пример #4
0
pres_entry_t* insert_phtable(str* pres_uri, int event, str* etag, char* sphere, int init_turn)
{
	unsigned int hash_code;
	pres_entry_t* p= NULL;
	int size;

	size= sizeof(pres_entry_t)+ pres_uri->len;
	p= (pres_entry_t*)shm_malloc(size);
	if(p== NULL)
	{
		ERR_MEM(SHARE_MEM);
	}
	memset(p, 0, size);

	size= sizeof(pres_entry_t);
	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;

	if(sphere)
	{
		p->sphere= (char*)shm_malloc(strlen(sphere)+ 1);
		if(p->sphere== NULL)
		{
			ERR_MEM(SHARE_MEM);
		}
		strcpy(p->sphere, sphere);
	}
	p->event= event;
	update_pres_etag(p, etag);

	hash_code= core_hash(pres_uri, NULL, phtable_size);
	lock_get(&pres_htable[hash_code].lock);

	p->next= pres_htable[hash_code].entries->next;
	pres_htable[hash_code].entries->next= p;

	p->last_turn = init_turn;

	lock_release(&pres_htable[hash_code].lock);

	return p;

error:
	if(p)
		shm_free(p);
	return NULL;
}
Пример #5
0
int release_dynamic_lock(struct sip_msg *msg, char *string)
{
	str ret;
	int hash;

	if (fixup_get_svalue(msg, (gparam_p)string, &ret) != 0) {
		LM_ERR("Get string from fixup param failed!\n");
		return -1;
	}

	hash = (int)core_hash(&ret, NULL, lock_pool_size);

	lock_set_release(dynamic_locks, hash);
	LM_DBG("Released dynamic lock----- %d\n", hash);

	return 1;
}
Пример #6
0
int lcache_htable_insert(cachedb_con *con,str* attr, str* value, int expires)
{
	lcache_entry_t* me, *it;
	int hash_code;
	int size;
	struct timeval start;

	size= sizeof(lcache_entry_t) + attr->len + value->len;

	me = (lcache_entry_t*)shm_malloc(size);
	if(me == NULL)
	{
		LM_ERR("no more shared memory\n");
		return -1;
	}
	memset(me, 0, size);

	start_expire_timer(start,local_exec_threshold);

	me->attr.s = (char*)me + (sizeof(lcache_entry_t));
	memcpy(me->attr.s, attr->s, attr->len);
	me->attr.len = attr->len;

	me->value.s = (char*)me + (sizeof(lcache_entry_t)) + attr->len;
	memcpy(me->value.s, value->s, value->len);
	me->value.len = value->len;
	if( expires != 0)
		me->expires = get_ticks() + expires;

	hash_code= core_hash( attr, 0, cache_htable_size);
	lock_get(&cache_htable[hash_code].lock);

	it = cache_htable[hash_code].entries;

	/* if a previous record for the same attr delete it */
	lcache_htable_remove_safe( *attr, &it);

	me->next = it;
	cache_htable[hash_code].entries = me;

	lock_release(&cache_htable[hash_code].lock);

	stop_expire_timer(start,local_exec_threshold,
	"cachedb_local insert",attr->s,attr->len,0);
	return 1;
}
Пример #7
0
int delete_phtable_query(str *pres_uri, int event, str* etag)
{
	pres_entry_t* p;
	unsigned int hash_code;

	hash_code = core_hash(pres_uri, 0, phtable_size);
	lock_get(&pres_htable[hash_code].lock);
	p = search_phtable_etag(pres_uri, event, etag, hash_code);
	if(p == NULL)
	{
		LM_ERR("Record not found [%.*s]\n", etag->len, etag->s);
		lock_release(&pres_htable[hash_code].lock);
		return -1;
	}
	delete_phtable(p, hash_code);
	lock_release(&pres_htable[hash_code].lock);
	return 0;
}
Пример #8
0
/*!
 * \brief Helper function that outputs a dialog via the RPC interface
 * \see rpc_print_dlgs
 * \param rpc RPC node that should be filled
 * \param c RPC void pointer
 * \param with_context if 1 then the dialog context will be also printed
 */
static void internal_rpc_print_single_dlg(rpc_t *rpc, void *c, int with_context) {
	str callid, from_tag;
	dlg_entry_t *d_entry;
	dlg_cell_t *dlg;
	unsigned int h_entry;

	if (rpc->scan(c, ".S.S", &callid, &from_tag) < 2) return;

	h_entry = core_hash( &callid, 0, d_table->size);
	d_entry = &(d_table->entries[h_entry]);
	dlg_lock( d_table, d_entry);
	for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) {
		if (match_downstream_dialog( dlg, &callid, &from_tag)==1) {
			internal_rpc_print_dlg(rpc, c, dlg, with_context);
		}
	}
	dlg_unlock( d_table, d_entry);
}
Пример #9
0
int delete_phtable(str* pres_uri, int event)
{
	unsigned int hash_code;
	pres_entry_t* p= NULL, *prev_p= NULL;

	hash_code= core_hash(pres_uri, NULL, phtable_size);

	lock_get(&pres_htable[hash_code].lock);
	
	p= search_phtable(pres_uri, event, hash_code);
	if(p== NULL)
	{
		LM_DBG("record not found\n");
		lock_release(&pres_htable[hash_code].lock);
		return 0;
	}
	
	p->publ_count--;
	if(p->publ_count== 0)
	{
		/* delete record */	
		prev_p= pres_htable[hash_code].entries;
		while(prev_p->next)
		{
			if(prev_p->next== p)
				break;
			prev_p= prev_p->next;
		}
		if(prev_p->next== NULL)
		{
			LM_ERR("record not found\n");
			lock_release(&pres_htable[hash_code].lock);
			return -1;
		}
		prev_p->next= p->next;
		if(p->sphere)
			shm_free(p->sphere);

		shm_free(p);
	}
	lock_release(&pres_htable[hash_code].lock);

	return 0;	
}
Пример #10
0
int lcache_htable_remove(cachedb_con *con,str* attr)
{
	int hash_code;
	struct timeval start;

	start_expire_timer(start,local_exec_threshold);

	hash_code= core_hash( attr, 0, cache_htable_size);
	lock_get(&cache_htable[hash_code].lock);

	lcache_htable_remove_safe( *attr, &cache_htable[hash_code].entries);

	lock_release(&cache_htable[hash_code].lock);

	stop_expire_timer(start,local_exec_threshold,
	"cachedb_local remove",attr->s,attr->len,0);

	return 0;
}
Пример #11
0
unsigned long insert_htable(ua_pres_t* presentity)
{
	unsigned int hash_code;
	str* s1;
	unsigned long pres_id;
	ua_pres_t* p;

	if(presentity->to_uri.s)
		s1 = &presentity->to_uri;
	else
		s1 = presentity->pres_uri;

	LM_DBG("to_uri= %.*s, watcher_uri= %.*s\n", s1->len, s1->s,
		(presentity->watcher_uri?presentity->watcher_uri->len:0),
		(presentity->watcher_uri?presentity->watcher_uri->s:0));

	hash_code= core_hash(s1, presentity->watcher_uri, 
			HASH_SIZE);
	presentity->hash_index = hash_code;
	LM_DBG("hash_code = %d\n", hash_code);

	lock_get(&HashT->p_records[hash_code].lock);

	p= HashT->p_records[hash_code].entity;

	presentity->db_flag= INSERTDB_FLAG;
	presentity->next= p->next;
	if(p->next)
	{
		presentity->local_index = p->next->local_index + 1;
	}
	else
		presentity->local_index = 0;

	p->next= presentity;

	pres_id = PRES_HASH_ID(presentity);

	lock_release(&HashT->p_records[hash_code].lock);

	return pres_id;
}
Пример #12
0
int dbt_db_del_table(dbt_cache_p _dc, const str *_s, int sync)
{
	dbt_table_p _tbc = NULL;
	int hash;
	int hashidx;
	if(!_dbt_cachetbl || !_dc || !_s || !_s->s || _s->len<=0)
		return -1;

	hash = core_hash(&_dc->name, _s, DBT_CACHETBL_SIZE);
	hashidx = hash % DBT_CACHETBL_SIZE;

	if(sync)
		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))
		{
			if(_tbc->prev)
				(_tbc->prev)->next = _tbc->next;
			else
				_dbt_cachetbl[hashidx].dtp = _tbc->next;

			if(_tbc->next)
				(_tbc->next)->prev = _tbc->prev;
			break;
		}
		_tbc = _tbc->next;
	}

	if(sync)
		lock_release(&_dbt_cachetbl[hashidx].sem);

	dbt_table_free(_tbc);

	return 0;
}
Пример #13
0
/*
 * Obtain a urecord pointer if the urecord exists in the table
 */
int get_ts_urecord(str* ruri, struct ts_urecord** _r)
{
	int sl, i, rurihash;
	ts_urecord_t* r;

	rurihash = core_hash(ruri, 0, 0);
	sl = rurihash&(t_table->size-1);
	r = t_table->entries[sl].first;

	for(i = 0; r!=NULL && i < t_table->entries[sl].n; i++) {
		if((r->rurihash==rurihash) && (r->ruri.len==ruri->len)
				&& !memcmp(r->ruri.s,ruri->s,ruri->len)){
			*_r = r;
			return 0;
		}
		r = r->next;
	}

	return 1;   /* Nothing found */
}
Пример #14
0
int get_pcontact(udomain_t* _d, str* _contact, struct pcontact** _c) {
	unsigned int sl, i, aorhash;
	struct pcontact* c;

	/* search in cache */
	aorhash = core_hash(_contact, 0, 0);
	sl = aorhash & (_d->size - 1);
	c = _d->table[sl].first;

	for (i = 0; i < _d->table[sl].n; i++) {
		if ((c->aorhash == aorhash) && (c->aor.len == _contact->len)
				&& !memcmp(c->aor.s, _contact->s, _contact->len)) {
			*_c = c;
			return 0;
		}

		c = c->next;
	}
	return 1; /* Nothing found */
}
Пример #15
0
/*!
 * \brief Obtain a impurecord pointer if the impurecord exists in domain
 * \param _d domain to search the record
 * \param _aor address of record
 * \param _r new created record
 * \return 0 if a record was found, 1 if nothing could be found
 */
int get_impurecord(udomain_t* _d, str* public_identity, struct impurecord** _r) {
    unsigned int sl, i, aorhash;
    impurecord_t* r;

    /* search in cache */
    aorhash = core_hash(public_identity, 0, 0);
    sl = aorhash & (_d->size - 1);
    r = _d->table[sl].first;

    for (i = 0; i < _d->table[sl].n; i++) {
	if ((r->aorhash == aorhash) && (r->public_identity.len == public_identity->len)
		&& !memcmp(r->public_identity.s, public_identity->s, public_identity->len)) {
	    *_r = r;
	    return 0;
	}

	r = r->next;
    }
    return 1; /* Nothing found */
}
Пример #16
0
int convert_temporary_dialog(ua_pres_t *dialog)
{
	ua_pres_t *temp_dialog;
	unsigned int hash_code;

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

	temp_dialog = get_temporary_dialog(dialog, hash_code);
	if (temp_dialog)
		delete_htable(temp_dialog, hash_code);
	else
		return -1;

	insert_htable(dialog, hash_code);

	lock_release(&HashT->p_records[hash_code].lock);

	return 1;
}
Пример #17
0
/* Treat Notify reply callback */
void notif_cback_func(struct cell *t, int cb_type, struct tmcb_params *params){
	int code = params->code;
	struct sm_subscriber* params_notify = (struct sm_subscriber*)(*params->param);
	unsigned int hash_code;

	LM_DBG("TREAT NOTIFY REPLY \n");
	LM_DBG("CODE: %d \n ", code);

	// verify if response is OK
	if (code >= 200 && code < 300){
		// response OK(2XX)
		if (params_notify->expires > 0){
			LM_DBG("REPLY OK timeout %d \n", params_notify->timeout);
			LM_DBG("REPLY OK expires %d \n", params_notify->expires);
			time_t rawtime;

			time(&rawtime);
			int time_now = (int)rawtime;
			LM_DBG("TIME : %d \n", (int)rawtime );

			// update timeout
			params_notify->timeout =  params_notify->expires + time_now;
			LM_DBG("TIMEOUT_NOTIFY: %d \n ", params_notify->timeout);
			return;
		}
		if (params_notify->dlg_id->status == TERMINATED){

			// delete subs_htable
			hash_code= core_hash(&params_notify->call_dlg_id->callid, 0, subst_size);
			LM_DBG("********************************************HASH_CODE%d\n", hash_code);
			LM_DBG("********************************************CALLID_STR%.*s\n", params_notify->call_dlg_id->callid.len, params_notify->call_dlg_id->callid.s);

			delete_shtable(subs_htable, hash_code, params_notify);
		}

	}else{
		// Response NOK
		LM_ERR("reply to NOTIFY NOK\n");
	}
	return;
}
Пример #18
0
/*!
 * \brief Create and initialize new record structure
 * \param ruri request uri
 * \param _r pointer to the new record
 * \return 0 on success, negative on failure
 */
int new_ts_urecord(str* ruri, ts_urecord_t** _r)
{
	*_r = (ts_urecord_t*)shm_malloc(sizeof(ts_urecord_t));
	if (*_r == 0) {
		LM_ERR("no more share memory\n");
		return -1;
	}
	memset(*_r, 0, sizeof(ts_urecord_t));

	(*_r)->ruri.s = (char*)shm_malloc(ruri->len);
	if ((*_r)->ruri.s == 0) {
		LM_ERR("no more share memory\n");
		shm_free(*_r);
		*_r = 0;
		return -2;
	}
	memcpy((*_r)->ruri.s, ruri->s, ruri->len);
	(*_r)->ruri.len = ruri->len;
	(*_r)->rurihash = core_hash(ruri, 0, 0);
	return 0;
}
Пример #19
0
int get_dynamic_lock(struct sip_msg *msg, char *string)
{
	str ret;
	int hash;

	if (((gparam_p)string)->type == GPARAM_TYPE_STR) {
		LM_INFO("Static string given! get_static_lock() function is better!\n");
	}

	if (fixup_get_svalue(msg, (gparam_p)string, &ret) != 0) {
		LM_ERR("Get string from fixup param failed!\n");
		return -1;
	}

	hash = (int)core_hash(&ret, NULL, lock_pool_size);

	LM_DBG("Getting dynamic lock----- %d\n", hash);
	lock_set_get(dynamic_locks, hash);
	LM_DBG("Got dynamic lock----- %d\n", hash);

	return 1;
}
Пример #20
0
int is_dialog(ua_pres_t* dialog)
{
	int ret_code= 0;
	unsigned int hash_code;
	str* s1;

	if(dialog->to_uri.s)
		s1 = &dialog->to_uri;
	else
		s1 = dialog->pres_uri;

	hash_code= core_hash(s1, dialog->watcher_uri, HASH_SIZE);
	lock_get(&HashT->p_records[hash_code].lock);

	if(get_dialog(dialog, hash_code)== NULL)
		ret_code= -1;
	else
		ret_code= 0;
	lock_release(&HashT->p_records[hash_code].lock);
	
	return ret_code;

}
Пример #21
0
/**
 * @brief Get a subscription from the subscription list based on the IMPI
 *  NB - does not return with a lock on the subscription but does increment ref count
 * @param impu string of impu to search for
 * @param s ims_subscription to be returned if found
 * @param leave_slot_locked if no subscription is found return with the slot locked (in case we want to add) 
 * @return 0 on success
 */
int get_subscription(str* impi_s, ims_subscription** s, int leave_slot_locked) {
    int subscription_hash, sl;
    ims_subscription* ptr;

    subscription_hash = core_hash(impi_s, 0, 0);
    sl = subscription_hash & (subs_hash_size - 1);
    lock_subscription_slot(sl);
    ptr = ims_subscription_list->slot[sl].first;
    while (ptr) {
        if ((impi_s->len == ptr->private_identity.len) && (memcmp(impi_s->s, ptr->private_identity.s, impi_s->len) == 0)) {
            LM_DBG("found an existing subscription for IMPI [%.*s]\n", impi_s->len, impi_s->s);
            (*s) = ptr;
            lock_subscription(ptr);
            ref_subscription_unsafe(ptr);
            unlock_subscription(ptr);
            unlock_subscription_slot(sl);
            return 0;
        }
        ptr = ptr->next;
    }
    if (!leave_slot_locked)
        unlock_subscription_slot(sl);
    return 1;
}
Пример #22
0
int new_pcontact(struct udomain* _d, str* _contact, struct pcontact_info* _ci, struct pcontact** _c)
{
	int i;
	ppublic_t* ppublic_ptr;
	int is_default = 1;
	struct sip_uri sip_uri;


	*_c = (pcontact_t*)shm_malloc(sizeof(pcontact_t));
	if (*_c == 0) {
		LM_ERR("no more shared memory\n");
		return -1;
	}
	memset(*_c, 0, sizeof(pcontact_t));

	LM_DBG("New contact [<%.*s>] with %d associated IMPUs in state: [%s]\n",
			_contact->len, _contact->s,
			_ci->num_public_ids,
			reg_state_to_string(_ci->reg_state));

	(*_c)->aor.s = (char*) shm_malloc(_contact->len);
	if ((*_c)->aor.s == 0) {
		LM_ERR("no more shared memory\n");
		shm_free(*_c);
		*_c = 0;
		return -2;
	}
	memcpy((*_c)->aor.s, _contact->s, _contact->len);
	(*_c)->aor.len = _contact->len;
	(*_c)->domain = (str*)_d;

	if (parse_uri((*_c)->aor.s, (*_c)->aor.len, &sip_uri) != 0) {
		LM_ERR("unable to determine contact host from uri [%.*s\n", (*_c)->aor.len, (*_c)->aor.s);
		shm_free((*_c)->aor.s);
		shm_free(*_c);
		*_c = 0;
		return -2;
	}
	(*_c)->contact_host.s = sip_uri.host.s;
	(*_c)->contact_host.len = sip_uri.host.len;
	(*_c)->contact_port = sip_uri.port_no;
	(*_c)->contact_user.s = sip_uri.user.s;
	(*_c)->contact_user.len = sip_uri.user.len;

	if (hashing_type==0) {
		(*_c)->aorhash = core_hash(_contact, 0, 0);
	} else {
		(*_c)->aorhash = core_hash(&(*_c)->contact_host, 0, 0);
	}
	(*_c)->expires = _ci->expires;
	(*_c)->reg_state = _ci->reg_state;

	// Add received Info:
	if (_ci->received_host.len > 0 && _ci->received_host.s) {
		(*_c)->received_host.s = (char*) shm_malloc(_ci->received_host.len);
		if ((*_c)->received_host.s == 0) {
			LM_ERR("no more share memory\n");
			shm_free((*_c)->aor.s);
			shm_free(*_c);
			*_c = 0;
			return -2;
		}
		memcpy((*_c)->received_host.s, _ci->received_host.s, _ci->received_host.len);
		(*_c)->received_host.len = _ci->received_host.len;
		(*_c)->received_port = _ci->received_port;
		(*_c)->received_proto = _ci->received_proto;
	}

	//setup public ids
	for (i=0; i<_ci->num_public_ids; i++) {
		if (i>0) is_default = 0; //only the first one is default - P-Associated-uri (first one is default)
		if (new_ppublic(&_ci->public_ids[i], is_default, &ppublic_ptr)!=0) {
			LM_ERR("unable to create new ppublic\n");
		} else {
			insert_ppublic(*_c, ppublic_ptr);
		}
	}
	//add the service routes
	if (_ci->num_service_routes > 0) {
		(*_c)->service_routes = shm_malloc(_ci->num_service_routes * sizeof(str));
		if (!(*_c)->service_routes) {
			LM_ERR("no more shm mem\n");
			goto out_of_memory;
		} else {
			for (i = 0; i < _ci->num_service_routes; i++) {
				STR_SHM_DUP((*_c)->service_routes[i], _ci->service_routes[i], "new_pcontact");
			}
			(*_c)->num_service_routes = _ci->num_service_routes;
		}
	}
	return 0;

out_of_memory:
	return -1;
}
Пример #23
0
int send_subscribe(subs_info_t* subs)
{
	ua_pres_t* presentity= NULL;
	str met= {"SUBSCRIBE", 9};
	str* str_hdr= NULL;
	int ret= -1;
	unsigned int hash_code=0;
	ua_pres_t* hentity= NULL;
	int expires;
	int flag;
	int result;
	uac_req_t uac_r;
	db1_res_t *res=NULL;
	ua_pres_t dbpres;
	str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0};
	dlg_t* td= NULL;


	memset(&dbpres, 0, sizeof(dbpres));
	dbpres.pres_uri = &pres_uri;
	dbpres.watcher_uri = &watcher_uri;
	dbpres.extra_headers = &extra_headers; 

	print_subs(subs);

	flag= subs->source_flag;
	if(subs->source_flag & XMPP_INITIAL_SUBS)
		subs->source_flag= XMPP_SUBSCRIBE;

	if(subs->expires< 0)
		expires= 3600;
	else
		expires= subs->expires;

	str_hdr= subs_build_hdr(subs->contact, expires, subs->event, 
			subs->extra_headers);
	if(str_hdr== NULL || str_hdr->s== NULL)
	{
		LM_ERR("while building extra headers\n");
		return -1;
	}

	if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction)
	{
		if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	/* generation of hash and getting lock moved from here to further down */

	if (dbmode==PUA_DB_ONLY)
	{
		presentity = get_dialog_puadb(subs->id, subs->pres_uri, &dbpres, &res);
	}
	else
	{
		ua_pres_t pres;

		memset(&pres, 0, sizeof(ua_pres_t));
		pres.pres_uri = subs->pres_uri;
		pres.watcher_uri = subs->watcher_uri;
		pres.flag = subs->source_flag;
		pres.id = subs->id;
		pres.event = subs->event;
		if (subs->remote_target)
			pres.remote_contact = *subs->remote_target;

		hash_code=core_hash(subs->pres_uri, subs->watcher_uri, HASH_SIZE);
		lock_get(&HashT->p_records[hash_code].lock);
		presentity= search_htable(&pres, hash_code);
	}

	/* if flag == INSERT_TYPE insert no matter what the search result is */
	if(subs->flag & INSERT_TYPE)
	{
		LM_DBG("A subscription request with insert type\n");
		goto insert;
	}
	
	if(presentity== NULL )
	{
		int size;
insert:
	
		if (subs->expires == 0)
		{
			/* Don't create a new dialog when expires == 0 */
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto done;
		}

		if(subs->flag & UPDATE_TYPE)
		{
			LM_DBG("request for a subscription with update type"
					" and no record found\n");
			subs->flag= INSERT_TYPE;
		}	
		hentity= subscribe_cbparam(subs, REQ_OTHER);
		if(hentity== NULL)
		{
			LM_ERR("while building callback"
					" param\n");
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		hentity->flag= flag;

		set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED,
				subs_cback_func, (void*)hentity);
		result= tmb.t_request_outside
			(&uac_r,						  /* Type of the message */
		subs->remote_target?subs->remote_target:subs->pres_uri,/* Request-URI*/
			subs->pres_uri,				  /* To */
			subs->watcher_uri,			  /* From */
			subs->outbound_proxy		  /* Outbound_proxy */	
			);
		if(result< 0)
		{
			LM_ERR("while sending request with t_request\n");
			if (uac_r.dialog != NULL)
			{
				uac_r.dialog->rem_target.s = 0;
				uac_r.dialog->dst_uri.s = 0;
				tmb.free_dlg(uac_r.dialog);
				uac_r.dialog = 0;
			}
			shm_free(hentity);
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);

			/* Although this is an error must not return -1 as the
			   calling function must continue processing. */
			ret = 0;
			goto error;
		}

		/* Now create a temporary hash table entry.
		   This is needed to deal with the race-hazard when NOTIFYs
		   arrive before the 2xx response to the SUBSCRIBE. */
		size = sizeof(ua_pres_t)+ 2 * sizeof(str) + (
			subs->pres_uri->len +
			subs->watcher_uri->len +
			uac_r.dialog->id.loc_tag.len +
			uac_r.dialog->id.call_id.len +
			subs->id.len) * sizeof(char);

		presentity= (ua_pres_t*)shm_malloc(size);
		if(presentity== NULL)
		{
			LM_ERR("no more share memory\n");
       			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		memset(presentity, 0, size);
		size= sizeof(ua_pres_t);

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

		presentity->watcher_uri= (str *) ((char *) presentity + size);
		size += sizeof(str);
		presentity->watcher_uri->s= (char *) presentity + size;
		memcpy(presentity->watcher_uri->s, subs->watcher_uri->s, subs->watcher_uri->len);
		presentity->watcher_uri->len = subs->watcher_uri->len;
		size += subs->watcher_uri->len;

		presentity->call_id.s = (char *) presentity + size;
		memcpy(presentity->call_id.s, uac_r.dialog->id.call_id.s, uac_r.dialog->id.call_id.len);
		presentity->call_id.len = uac_r.dialog->id.call_id.len;
		size += uac_r.dialog->id.call_id.len;

		presentity->from_tag.s = (char *) presentity + size;
		memcpy(presentity->from_tag.s, uac_r.dialog->id.loc_tag.s, uac_r.dialog->id.loc_tag.len);
		presentity->from_tag.len= uac_r.dialog->id.loc_tag.len;
		size += uac_r.dialog->id.loc_tag.len;

		presentity->id.s = (char *) presentity+ size;
		memcpy(presentity->id.s, subs->id.s, subs->id.len);
		presentity->id.len = subs->id.len;
		size += subs->id.len;

		presentity->event = subs->event;
		presentity->flag = subs->source_flag;
		presentity->cseq = uac_r.dialog->loc_seq.value;

		/* Set the temporary record expiry for 2 * 64T1 seconds from now */
		presentity->expires= (int)time(NULL) + 64;
		presentity->desired_expires= presentity->expires;

		if (dbmode==PUA_DB_ONLY)
		{
			insert_dialog_puadb(presentity);
			shm_free(presentity);
		}
		else
		{
			insert_htable(presentity, hash_code);
			lock_release(&HashT->p_records[hash_code].lock);
		}

		uac_r.dialog->rem_target.s = 0;
		uac_r.dialog->dst_uri.s = 0;
		tmb.free_dlg(uac_r.dialog);
		uac_r.dialog = 0;
	}
	else
	{
		if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE)
		{
			LM_INFO("attempting to re-SUBSCRIBE on internal (rls_update_subs()) update - skipping\n");
			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto done;
		}

		if (presentity->to_tag.len == 0)
		{
			if (subs->expires > 0)
				LM_WARN("attempting to re-SUBSCRIBE to a temporary (non-established) dialog - skipping\n");
			else
			{
				LM_WARN("attempting to un-SUBSCRIBE from a temporary (non-established) dialog - skipping and deleting dialog\n");
				if (dbmode==PUA_DB_ONLY)
					delete_dialog_puadb(presentity);
				else
					delete_htable(presentity, hash_code);
			}

			if (dbmode != PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto done;
		}

		td= pua_build_dlg_t(presentity);
		if(td== NULL)
		{
			LM_ERR("while building tm dlg_t structure");
			if (dbmode!=PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
				
		hentity= subs_cbparam_indlg(presentity, expires, REQ_OTHER);
		if(hentity== NULL)
		{
			LM_ERR("while building callback param\n");
			if (dbmode!=PUA_DB_ONLY)
				lock_release(&HashT->p_records[hash_code].lock);
			goto error;
		}
		if (dbmode!=PUA_DB_ONLY)
			lock_release(&HashT->p_records[hash_code].lock);

		LM_DBG("event parameter: %d\n", hentity->event);	

		set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED,
				subs_cback_func, (void*)hentity);
		result= tmb.t_request_within(&uac_r);
		if(result< 0)
		{
			shm_free(hentity);
			hentity= NULL;
			LM_ERR("while sending request with t_request\n");
			goto error;
		}
	}


done:
	if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
	{
		if (pua_dbf.end_transaction(pua_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	ret = 0;

error:
	pua_free_tm_dlg(td);
	pkg_free(str_hdr);
	free_results_puadb(res);

	if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction)
	{
		if (pua_dbf.abort_transaction(pua_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

	return ret;
}
Пример #24
0
void subs_cback_func(struct cell *t, int cb_type, struct tmcb_params *ps)
{
	struct sip_msg* msg= NULL;
	int lexpire= 0;
	unsigned int cseq;
	ua_pres_t* presentity= NULL, *hentity= NULL;
	struct to_body *pto = NULL, TO = {0}, *pfrom = NULL;
	int size= 0;
	unsigned int hash_code;
	int flag ;
	str record_route= {0, 0};
	int rt;
	str contact;
	int initial_request = 0;
	int end_transaction = 1;

	if( ps->param== NULL || *ps->param== NULL )
	{
		LM_ERR("null callback parameter\n");
		return;
	}

	if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction)
	{
		if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0)
		{
			LM_ERR("in start_transaction\n");
			goto error;
		}
	}

	LM_DBG("completed with status %d\n",ps->code) ;
	hentity= (ua_pres_t*)(*ps->param);
	hash_code= core_hash(hentity->pres_uri,hentity->watcher_uri,
				HASH_SIZE);
	flag= hentity->flag;
	if(hentity->flag & XMPP_INITIAL_SUBS)
		hentity->flag= XMPP_SUBSCRIBE;

	/* get dialog information from reply message: callid, to_tag, from_tag */
	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n ");
		goto error;
	}

	if(msg== FAKED_REPLY)
	{
		struct hdr_field *callid = NULL, *from = NULL;
		struct to_body FROM = {0};

		callid = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field));
		if (callid == NULL)
		{
			LM_ERR("Out of memory\n");
			goto faked_error;
		}
		memset(callid, 0, sizeof(struct hdr_field));
		get_hdr_field(t->callid.s, t->callid.s + t->callid.len, callid);
		hentity->call_id = callid->body;

		from = (struct hdr_field *) pkg_malloc(sizeof(struct hdr_field));
		if (from == NULL)
		{
			LM_ERR("Out of memory\n");
			goto faked_error;
		}
		memset(from, 0, sizeof(struct hdr_field));
		get_hdr_field(t->from.s, t->from.s + t->from.len, from);
		parse_to(from->body.s, from->body.s + from->body.len + 1, &FROM);
		if(FROM.uri.len <= 0) 
		{
			LM_ERR("'From' header NOT parsed\n");
			goto faked_error;
		}
	
		hentity->call_id = callid->body;
		hentity->from_tag = (&FROM)->tag_value;
		hentity->to_tag.s = NULL;
		hentity->to_tag.len = 0;

		find_and_delete_dialog(hentity, hash_code);
faked_error:
		if (callid) pkg_free(callid);
		free_to_params(&FROM);
		if (from) pkg_free(from);
		goto done;
	}
	
	if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("when parsing headers\n");
		goto error;
	}

	if(ps->rpl->expires && msg->expires->body.len > 0)
	{
		if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
		{
			LM_ERR("cannot parse Expires header\n");
			goto error;
		}
		lexpire = ((exp_body_t*)msg->expires->parsed)->val;
		LM_DBG("lexpire= %d\n", lexpire);
	}

	/*if initial request */
	if(hentity->call_id.s== NULL)
	{
		initial_request = 1;

		if( msg->callid==NULL || msg->callid->body.s==NULL)
		{
			LM_ERR("cannot parse callid header\n");
			goto error;
		}
		
		if (!msg->from || !msg->from->body.s)
		{
			LM_ERR("cannot find 'from' header!\n");
			goto error;
		}
		if (msg->from->parsed == NULL)
		{
			if ( parse_from_header( msg )<0 ) 
			{
				LM_ERR("cannot parse From header\n");
				goto error;
			}
		}
		pfrom = (struct to_body*)msg->from->parsed;
	
		if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
		{
			LM_ERR("no from tag value present\n");
			goto error;
		}

		hentity->call_id=  msg->callid->body;
		hentity->from_tag= pfrom->tag_value;

		if(ps->code >= 300 || lexpire == 0)
		{
			hentity->to_tag.s = NULL;
			hentity->to_tag.len = 0;
			find_and_delete_dialog(hentity, hash_code);
			goto done;
		}

		if( msg->to==NULL || msg->to->body.s==NULL)
		{
			LM_ERR("cannot parse TO header\n");
			goto error;
		}			
		if(msg->to->parsed != NULL)
		{
			pto = (struct to_body*)msg->to->parsed;
			LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
		}
		else
		{
			parse_to(msg->to->body.s,msg->to->body.s +
				msg->to->body.len + 1, &TO);
			if(TO.uri.len <= 0) 
			{
				LM_ERR("'To' header NOT parsed\n");
				goto error;
			}
			pto = &TO;
		}			
		if( pto->tag_value.s ==NULL || pto->tag_value.len == 0)
		{
			LM_ERR("no to tag value present\n");
			goto error;
		}
		hentity->to_tag= pto->tag_value;
	}

	if(ps->code >= 300 )
	{	/* if an error code and a stored dialog delete it and try to send 
		   a subscription with type= INSERT_TYPE, else return*/	
		
		subs_info_t subs;

		hentity->to_tag.s = NULL;
		hentity->to_tag.len = 0;
		find_and_delete_dialog(hentity, hash_code);

		if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction)
		{
			if (pua_dbf.end_transaction(pua_db) < 0)
			{
				LM_ERR("in end_transaction\n");
				goto error;
			}
		}

		end_transaction = 0;

		/* Redirect if the response 3XX */
		memset(&subs, 0, sizeof(subs_info_t));
		subs.pres_uri= hentity->pres_uri; 
		subs.watcher_uri= hentity->watcher_uri;
		subs.contact= &hentity->contact;

		if(hentity->remote_contact.s)
			subs.remote_target= &hentity->remote_contact;

		if(hentity->desired_expires== 0)
			subs.expires= -1;
		else
		if(hentity->desired_expires< (int)time(NULL))
			subs.expires= 0;
		else
			subs.expires= hentity->desired_expires- (int)time(NULL)+ 3;

		subs.flag= INSERT_TYPE;
		subs.source_flag= flag;
		subs.event= hentity->event;
		subs.id= hentity->id;
		subs.outbound_proxy= hentity->outbound_proxy;
		subs.extra_headers= hentity->extra_headers;
		subs.cb_param= hentity->cb_param;
	
		if(send_subscribe(&subs)< 0)
		{
			LM_ERR("when trying to send SUBSCRIBE\n");
			goto error;
		}
		goto done;
	}

	if(lexpire== 0 )
	{
		LM_DBG("lexpire= 0 Delete from hash table");
		find_and_delete_dialog(hentity, hash_code);
		goto done;
	}

	/* extract the contact */
	if(msg->contact== NULL || msg->contact->body.s== NULL)
	{
		LM_ERR("no contact header found");
		goto error;
	}
	if( parse_contact(msg->contact) <0 )
	{
		LM_ERR(" cannot parse contact header\n");
		goto error;
	}
	if(msg->contact->parsed == NULL)
	{
		LM_ERR("cannot parse contact header\n");
		goto error;
	}
	contact = ((contact_body_t* )msg->contact->parsed)->contacts->uri;

	if( msg->cseq==NULL || msg->cseq->body.s==NULL)
	{
		LM_ERR("cannot parse cseq header\n");
		goto error;
	}

	if( str2int( &(get_cseq(msg)->number), &cseq)< 0)
	{
		LM_ERR("while converting str to int\n");
		goto error;
	}

	if(initial_request == 0)
	{
		hentity->cseq = cseq;
		find_and_update_dialog(hentity, hash_code, lexpire, &contact);
		goto done;
	}

	/*process record route and add it to a string*/
	if (msg->record_route!=NULL)
	{
		rt = print_rr_body(msg->record_route, &record_route, 1, 0);
		if(rt != 0)
		{
			LM_ERR("parsing record route [%d]\n", rt);	
			record_route.s=NULL;
			record_route.len=0;
		}
	}

	size= sizeof(ua_pres_t)+ 2*sizeof(str)+( pto->uri.len+
		pfrom->uri.len+ pto->tag_value.len+ pfrom->tag_value.len
		+msg->callid->body.len+ record_route.len+ hentity->contact.len+
		hentity->id.len )*sizeof(char);

	if(hentity->extra_headers)
		size+= sizeof(str)+ hentity->extra_headers->len*sizeof(char);

	presentity= (ua_pres_t*)shm_malloc(size);
	if(presentity== NULL)
	{
		LM_ERR("no more share memory\n");
		goto error;
	}
	
	memset(presentity, 0, size);
	size= sizeof(ua_pres_t);

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

	presentity->watcher_uri= (str*)( (char*)presentity+ size);
	size+= sizeof(str);
	presentity->watcher_uri->s= (char*)presentity+ size;
	memcpy(presentity->watcher_uri->s, pfrom->uri.s, pfrom->uri.len);
	presentity->watcher_uri->len= pfrom->uri.len;
	size+= pfrom->uri.len;

	presentity->call_id.s= (char*)presentity + size;
	memcpy(presentity->call_id.s,msg->callid->body.s, 
		msg->callid->body.len);
	presentity->call_id.len= msg->callid->body.len;
	size+= presentity->call_id.len;

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

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

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

	presentity->contact.s= (char*)presentity + size;
	memcpy(presentity->contact.s, hentity->contact.s, hentity->contact.len);
	presentity->contact.len= hentity->contact.len;
	size+= hentity->contact.len;

	if(hentity->id.s)
	{
		presentity->id.s=(char*)presentity+ size;
		memcpy(presentity->id.s, hentity->id.s, 
			hentity->id.len);
		presentity->id.len= hentity->id.len; 
		size+= presentity->id.len;
	}

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

	/* write the remote contact filed */
	presentity->remote_contact.s= (char*)shm_malloc(contact.len* sizeof(char));
	if(presentity->remote_contact.s==NULL)
	{
		ERR_MEM(SHARE_MEM);
	}
	memcpy(presentity->remote_contact.s, contact.s, contact.len);
	presentity->remote_contact.len= contact.len;

	presentity->event|= hentity->event;
	presentity->flag= hentity->flag;
	presentity->etag.s= NULL;
	presentity->cseq= cseq;
	presentity->desired_expires= hentity->desired_expires;
	presentity->expires= lexpire+ (int)time(NULL);
	if(BLA_SUBSCRIBE & presentity->flag)
	{
		LM_DBG("BLA_SUBSCRIBE FLAG inserted\n");
	}	
	LM_DBG("record for subscribe from %.*s to %.*s inserted in datatbase\n",
			presentity->watcher_uri->len, presentity->watcher_uri->s,
			presentity->pres_uri->len, presentity->pres_uri->s);

	if (dbmode==PUA_DB_ONLY)
	{
		if (pua_dbf.end_transaction)
		{
			if (pua_dbf.end_transaction(pua_db) < 0)
			{
				LM_ERR("in end_transaction\n");
				goto error;
			}
		}

		if (pua_dbf.start_transaction)
		{
			if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0)
			{
				LM_ERR("in start_transaction\n");
				goto error;
			}
		}

		if (convert_temporary_dialog_puadb(presentity) < 0)
		{
			LM_ERR("Could not convert temporary dialog into a dialog\n");
			goto error;
		}
	}
	else
	{
		if (convert_temporary_dialog(presentity) < 0)
		{
			LM_ERR("Could not convert temporary dialog into a dialog\n");
			goto error;
		}
	}

done:
	if(hentity->ua_flag == REQ_OTHER)
	{
		hentity->flag= flag;
		run_pua_callbacks( hentity, msg);
	}

	if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction && end_transaction)
	{
		if (pua_dbf.end_transaction(pua_db) < 0)
		{
			LM_ERR("in end_transaction\n");
			goto error;
		}
	}

	goto end;

error:	
        if (presentity)
	{
		if (presentity->remote_contact.s) shm_free(presentity->remote_contact.s);
	 	shm_free(presentity);
	}

	if(record_route.s)
		pkg_free(record_route.s);

	if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction)
	{
		if (pua_dbf.abort_transaction(pua_db) < 0)
			LM_ERR("in abort_transaction\n");
	}

end:

	if(hentity)
	{	
		shm_free(hentity);
		hentity= NULL;
	}

	free_to_params(&TO);
	return;
}
Пример #25
0
str* client_new(client_info_t* ci,b2b_notify_t b2b_cback,
		b2b_add_dlginfo_t add_dlginfo, str* param)
{
	int result;
	b2b_dlg_t* dlg;
	unsigned int hash_index;
	str* callid = NULL;
	int size;
	str ehdr = {0, 0};
	str* b2b_key_shm = NULL;
	dlg_t td;
	str from_tag;
	str random_info = {0, 0};

	if(ci == NULL || b2b_cback == NULL || param== NULL)
	{
		LM_ERR("Wrong parameters.\n");
		return NULL;
	}
	if(param && param->len > B2BL_MAX_KEY_LEN)
	{
		LM_ERR("parameter too long, received [%d], maximum [%d]\n",
				param->len, B2BL_MAX_KEY_LEN);
		return 0;
	}

	hash_index = core_hash(&ci->from_uri, &ci->to_uri, client_hsize);

	if(ci->from_tag)
		from_tag = *ci->from_tag;
	else
		generate_tag(&from_tag, &ci->from_uri, ci->extra_headers);

	/* create a dummy b2b dialog structure to be inserted in the hash table*/
	size = sizeof(b2b_dlg_t) + ci->to_uri.len + ci->from_uri.len
		+ ci->from_dname.len + ci->to_dname.len +
		from_tag.len + ci->local_contact.len + B2B_MAX_KEY_SIZE + B2BL_MAX_KEY_LEN;

	/* create record in hash table */
	dlg = (b2b_dlg_t*)shm_malloc(size);
	if(dlg == NULL)
	{
		LM_ERR("No more shared memory\n");
		return 0;
	}
	memset(dlg, 0, size);
	size = sizeof(b2b_dlg_t);

	CONT_COPY(dlg, dlg->from_uri, ci->from_uri);
	CONT_COPY(dlg, dlg->to_uri, ci->to_uri);
	if(ci->to_dname.s)
		CONT_COPY(dlg, dlg->to_dname, ci->to_dname);
	if(ci->from_dname.s)
		CONT_COPY(dlg, dlg->from_dname, ci->from_dname);
	CONT_COPY(dlg, dlg->tag[CALLER_LEG], from_tag);
	CONT_COPY(dlg, dlg->contact[CALLER_LEG], ci->local_contact);

	if(param && param->s)
	{
		dlg->param.s = (char*)dlg + size;
		memcpy(dlg->param.s, param->s, param->len);
		dlg->param.len = param->len;
		size+= B2BL_MAX_KEY_LEN;
	}
	dlg->b2b_cback = b2b_cback;
	dlg->add_dlginfo = add_dlginfo;
	if(parse_method(ci->method.s, ci->method.s+ci->method.len, &dlg->last_method)< 0)
	{
		LM_ERR("wrong method %.*s\n", ci->method.len, ci->method.s);
		shm_free(dlg);
		goto error;
	}
	dlg->state = B2B_NEW;
	dlg->cseq[CALLER_LEG] =(ci->cseq?ci->cseq:1);
	dlg->send_sock = ci->send_sock;

	/* if the callid should be the same in more instances running at the same time (replication)*/
	if(!replication_mode)
	{
		srand(get_uticks());
		random_info.s = int2str(rand(), &random_info.len);
	}

	dlg->send_sock = ci->send_sock;
	dlg->id = core_hash(&from_tag, random_info.s?&random_info:0, HASH_SIZE);

	/* callid must have the special format */
	dlg->db_flag = NO_UPDATEDB_FLAG;
	callid = b2b_htable_insert(client_htable, dlg, hash_index, B2B_CLIENT, 0);
	if(callid == NULL)
	{
		LM_ERR("Inserting new record in hash table failed\n");
		shm_free(dlg);
		goto error;
	}

	if(b2breq_complete_ehdr(ci->extra_headers, &ehdr, ci->body,
				&ci->local_contact)< 0)
	{
		LM_ERR("Failed to complete extra headers\n");
		goto error;
	}

	/* copy the key in shared memory to transmit it as a parameter to the tm callback */
	b2b_key_shm = b2b_key_copy_shm(callid);
	if(b2b_key_shm== NULL)
	{
		LM_ERR("no more shared memory\n");
		goto error;
	}
	CONT_COPY(dlg, dlg->callid, (*callid));

	/* create the tm dialog structure with the a costum callid */
	memset(&td, 0, sizeof(dlg_t));
	td.loc_seq.value = dlg->cseq[CALLER_LEG];
	dlg->last_invite_cseq = dlg->cseq[CALLER_LEG];
	td.loc_seq.is_set = 1;

	td.id.call_id = *callid;
	td.id.loc_tag = from_tag;
	td.id.rem_tag.s = 0;
	td.id.rem_tag.len = 0;

	td.rem_uri = ci->to_uri;
	if(ci->req_uri.s)
		td.rem_target    = ci->req_uri;
	else
		td.rem_target    = ci->to_uri;
	if(td.rem_target.s[0] == '<')
	{
		td.rem_target.s++;
		td.rem_target.len-=2;
	}

	td.rem_dname  = ci->to_dname;

	td.loc_uri    = ci->from_uri;
	td.loc_dname  = ci->from_dname;

	td.state= DLG_CONFIRMED;
	td.T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ;

	td.send_sock = ci->send_sock;

	if(ci->dst_uri.len)
		td.obp = ci->dst_uri;

	td.avps = ci->avps;

	tmb.setlocalTholder(&dlg->uac_tran);

	/* send request */
	result= tmb.t_request_within
		(&ci->method,          /* method*/
		&ehdr,                 /* extra headers*/
		ci->body,              /* body*/
		&td,                   /* dialog structure*/
		b2b_client_tm_cback,   /* callback function*/
		b2b_key_shm,
		shm_free_param);       /* function to release the parameter*/

	if(td.route_set)
		pkg_free(td.route_set);
	if(result< 0)
	{
		LM_ERR("while sending request with t_request\n");
		pkg_free(callid);
		shm_free(b2b_key_shm);
		return NULL;
	}
	tmb.setlocalTholder(NULL);

	LM_DBG("new client entity [%p] callid=[%.*s] tag=[%.*s] param=[%.*s]"
			" last method=[%d] dlg->uac_tran=[%p]\n",
			dlg, callid->len, callid->s,
			dlg->tag[CALLER_LEG].len, dlg->tag[CALLER_LEG].s,
			dlg->param.len, dlg->param.s, dlg->last_method, dlg->uac_tran);

	return callid;

error:
	if(callid)
		pkg_free(callid);
	return NULL;
}
Пример #26
0
static int load_sca_info_from_db(void)
{
	db_res_t * res = NULL;
	db_val_t * values;
	db_row_t * rows;
	int i, j, nr_rows;
	unsigned int valid_record;
	unsigned int n_result_cols = 0;
	unsigned int shared_line_col, watchers_col;
	unsigned int app_shared_entity_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_state_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_info_uri_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_info_appearance_uri_col[MAX_APPEARANCE_INDEX];
	unsigned int app_b2bl_key_col[MAX_APPEARANCE_INDEX];
	db_key_t q_cols[SCA_TABLE_TOTAL_COL_NO];

	str shared_line, watchers_csv;
	//str_lst_t *watchers;
	//unsigned int size, watcher_size, watchers_no;
	//unsigned int size;
	unsigned int hash_index;
	//char *p;
	b2b_sca_record_t *record;
	b2b_sca_call_t *call;
	unsigned int shared_entity, appearance_index, call_state;
	str call_info_uri, call_info_apperance_uri, b2bl_key;
	b2bl_cb_ctx_t *cb_params;

	if(use_sca_table()) return -1;

	q_cols[shared_line_col = n_result_cols++] = &shared_line_column;
	q_cols[watchers_col = n_result_cols++] = &watchers_column;

	for (i=0; i<MAX_APPEARANCE_INDEX; i++) {
		q_cols[app_shared_entity_col[i]	= n_result_cols++] = &app_shared_entity_column[i];
		q_cols[app_call_state_col[i] = n_result_cols++] = &app_call_state_column[i];
		q_cols[app_call_info_uri_col[i] = n_result_cols++] = &app_call_info_uri_column[i];
		q_cols[app_call_info_appearance_uri_col[i] = n_result_cols++] =
						&app_call_info_appearance_uri_column[i];
		q_cols[app_b2bl_key_col[i] = n_result_cols++] = &app_b2bl_key_column[i];
	}

	/* select the whole tabel and all the columns */
	if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) {
		if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0,
				SCA_TABLE_TOTAL_COL_NO, 0, 0) < 0) {
			LM_ERR("Error while querying (fetch) database\n");
			return -1;
		}
		if(sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0){
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0,
				SCA_TABLE_TOTAL_COL_NO, 0, &res) < 0) {
			LM_ERR("Error while querying database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	do {
		LM_DBG("loading [%i] records from db\n", nr_rows);
		rows = RES_ROWS(res);
		/* for every row/record */
		for(i=0; i<nr_rows; i++){
			values = ROW_VALUES(rows + i);
			if (VAL_NULL(values+shared_line_col) || VAL_NULL(values+watchers_col)) {
				LM_ERR("columns [%.*s] or/and [%.*s] cannot be null -> skipping\n",
					shared_line_column.len, shared_line_column.s,
					watchers_column.len, watchers_column.s);
				continue;
			}
			shared_line.s = (char*)values[shared_line_col].val.string_val;
			shared_line.len = strlen(shared_line.s);

			watchers_csv.s = (char*)values[watchers_col].val.string_val;
			watchers_csv.len = strlen(watchers_csv.s);

			record = restore_record(&shared_line, &watchers_csv);
			if (record == NULL)
				goto error;
			hash_index = core_hash(&shared_line, NULL, b2b_sca_hsize);

			j = 0;
			while (j < MAX_APPEARANCE_INDEX) {
				if(	VAL_NULL(values + app_shared_entity_col[j]) ||
					VAL_NULL(values + app_call_state_col[j]) ||
					VAL_NULL(values + app_call_info_uri_col[j]) ||
					VAL_NULL(values + app_call_info_appearance_uri_col[j]) ||
					VAL_NULL(values + app_b2bl_key_col[j]) ) {
					goto cont;
				}
				appearance_index = j + 1;
				/* 1 - get shared_entity */
				shared_entity = values[app_shared_entity_col[j]].val.int_val;
				if (shared_entity!=0 && shared_entity!=1) {
					LM_ERR("Unexpected shared_entity [%d] "
						"for shared_line [%.*s]\n",
						shared_entity, shared_line.len, shared_line.s);
					goto cont;
				}
				/* 2 - get call_state */
				call_state = values[app_call_state_col[j]].val.int_val;
				if (call_state == IDLE_STATE) {
					LM_DBG("empty call[%d]\n", appearance_index);
					goto cont;
				}
				if (call_state > MAX_INDEX_STATE) {
					LM_ERR("Unexpected call_state [%d] for shared_line [%.*s]\n",
						call_state, shared_line.len, shared_line.s);
					goto cont;
				}
				/* 3 - get call_info_uri */
				call_info_uri.s =
					(char*)values[app_call_info_uri_col[j]].val.string_val;
				if (call_info_uri.s)
					call_info_uri.len = strlen(call_info_uri.s);
				else {
					LM_ERR("Missing call_info_uri for shared_line [%.*s][%d]\n",
						shared_line.len, shared_line.s, appearance_index);
					goto cont;
				}
				LM_DBG("call_info_uri=[%.*s]\n",
					call_info_uri.len, call_info_uri.s);
				/* 4 - get call_info_apperance_uri */
				call_info_apperance_uri.s =
					(char*)
					values[app_call_info_appearance_uri_col[j]].val.string_val;
				if (call_info_apperance_uri.s)
					call_info_apperance_uri.len =
						strlen(call_info_apperance_uri.s);
				else {
					LM_ERR("Missing call_info_apperance_uri for "
						"shared_line [%.*s][%d]\n",
						shared_line.len, shared_line.s, appearance_index);
					goto cont;
				}
				LM_DBG("call_info_apperance_uri=[%.*s]\n",
					call_info_apperance_uri.len, call_info_apperance_uri.s);
				/* 5 - get b2bl_key */
				b2bl_key.s = (char*)values[app_b2bl_key_col[j]].val.string_val;
				if (b2bl_key.s) {
					b2bl_key.len = strlen(b2bl_key.s);
					if (b2bl_key.len > B2BL_MAX_KEY_LEN) {
						LM_ERR("buffer overflow on b2bl_key [%.*s]"
							" for shared_line [%.*s][%d]\n",
							b2bl_key.len, b2bl_key.s,
							shared_line.len, shared_line.s,
							appearance_index);
						goto cont;
					}
					LM_DBG("b2bl_key=[%.*s]\n", b2bl_key.len, b2bl_key.s);
				} else {
					LM_ERR("Missing b2bl_key for shared_line [%.*s][1]\n",
						shared_line.len, shared_line.s);
					goto cont;
				}
				/* restore the call */
				call = restore_call(record, appearance_index,
					shared_entity, call_state,
					&call_info_uri, &call_info_apperance_uri);
				if (call == NULL) {
					goto error;
				}
				/* update record */
				if (0!=b2b_sca_update_call_record_key(call, &b2bl_key)) {
					LM_ERR("Unable to update b2bl_key [%.*s]\n",
						b2bl_key.len, b2bl_key.s);
					shm_free(call);
					call = NULL;
					record->call[appearance_index-1] = NULL;
					goto cont;
				}
				/* Prepare b2b_logic callback params. */
				cb_params = build_cb_params(hash_index,
							&shared_line, appearance_index);
				if (cb_params == NULL) {
					LM_ERR("Unable to build cb_params\n");
					goto error;
				}
				/* re-register callbacks */
				if(b2bl_api.register_cb(&b2bl_key, &sca_logic_notify, cb_params,
					B2B_RE_INVITE_CB|B2B_CONFIRMED_CB|B2B_DESTROY_CB) != 0){
					LM_ERR("Unable register b2b cb\n");
					shm_free(call);
					call = NULL;
					record->call[appearance_index-1] = NULL;
					goto cont;
				}
cont:
				j++;
			}

			valid_record = j = 0;
			while (j < MAX_APPEARANCE_INDEX) {
				if (record->call[j]) {
					valid_record = 1;
					goto check_valid_record;
				}
				j++;
			}
check_valid_record:
			if (valid_record) {
				b2b_sca_print_record(record);
				insert_record(hash_index, record);
			} else {
				LM_DBG("removing the record from db!\n");
				delete_sca_info_from_db(record);
			}
			LM_DBG("Done\n");
		}

		/* any more data to be fetched ?*/
		if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) {
			if (sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0) {
				LM_ERR("fetching more rows failed\n");
				goto error;
			}
			nr_rows = RES_ROW_N(res);
		} else {
			nr_rows = 0;
		}
	}while (nr_rows>0);

	sca_dbf.free_result(sca_db_handle, res);
	return 0;
error:
	sca_dbf.free_result(sca_db_handle, res);
	return -1;
}
Пример #27
0
/* Treat Notify to Subscriber Dialog in scenario III*/
int treat_notify(struct sip_msg *msg) {

	int resp = 1;
	struct sm_subscriber*  cell_subs;
	int expires= 0;
	char *subs_state, *subs_expires;
	str callid_orig;
	str from_tag;
	struct notify_body* notify_body = NULL;
	time_t rawtime;
	int time_now;
	int version;
	char *version_init, *version_end, *version_aux;
	int size_version;
	unsigned int hash_code;
	str callid_event;
	static str msg200={"OK Notify",sizeof("OK Notify")-1};
	static str msg481={"Subscription does not exist",sizeof("Subscription does not exist")-1};
	static str msg489={"Bad Event",sizeof("Bad Event")-1};
	static str msg400={"Bad Request",sizeof("Bad Request")-1};

	if(!check_event_header(msg)){
		LM_ERR("event header type not allow\n");
		if(!eme_tm.t_reply(msg,489,&msg489)){
			LM_ERR("t_reply (489)\n");
		}
		return 0;
	}

	if ( parse_headers(msg,HDR_EOH_F, 0) == -1 ){
		LM_ERR("error in parsing headers\n");
		return 0;
	}

	// get callid from Notify
	if( msg->callid==NULL || msg->callid->body.s==NULL){
		LM_ERR("reply without callid header\n");
		return 0;
	}
	callid_event = msg->callid->body;
	LM_DBG("CALLID: %.*s \n ", callid_event.len, callid_event.s );

	/* look for cell in list linked subs_pt with same dialog Id*/
	cell_subs = get_subs_cell(msg, callid_event);
	if(cell_subs == NULL){
		if(!eme_tm.t_reply(msg,481,&msg481)){
			LM_ERR("t_reply (481)\n");
		}
		return 0;
	}

	LM_DBG("STATUS: %d \n ", cell_subs->dlg_id->status);
	LM_DBG("TIMEOUT NOTIFY: %d \n ", cell_subs->timeout);

	/* get in Subscription_state header: state and expire */
	if(!get_subscription_state_header(msg, &subs_state, &subs_expires)){
		LM_ERR("invalid body of Subscription_state header\n");
		if(!eme_tm.t_reply(msg,400,&msg400)){
			LM_ERR("t_reply (400)\n");
		}
		return 0;
	}
	LM_DBG("STATE: %s\n ", subs_state);
	LM_DBG("SUBS_EXPIRES: %s\n ", subs_expires);

	time(&rawtime);
	time_now = (int)rawtime;

	/* analise state value*/
	if (strcmp(subs_state, "active") == 0){
		cell_subs->dlg_id->status = ACTIVE;
		cell_subs->expires = atoi(subs_expires);
		cell_subs->timeout =  cell_subs->expires + time_now;
	}else{
		if (strcmp(subs_state, "pending") == 0){
			cell_subs->dlg_id->status = PENDING ;
			cell_subs->expires = atoi(subs_expires);
			cell_subs->timeout =  TIMER_N + time_now;
		}else{
			if(strcmp(subs_state, "terminated") == 0){

				/* state is terminated indicate that subcriber dialog finish
				   then pull cell of the list linked and send esct to VPC*/
				LM_DBG(" --- CLEAR CELL \n");
				callid_orig = cell_subs->call_dlg_id->callid;
				from_tag = cell_subs->call_dlg_id->local_tag;

				LM_DBG(" --- CALLID_ORIG %.*s \n", callid_orig.len, callid_orig.s);
				LM_DBG(" --- FROM_TAG_ORIG %.*s \n", from_tag.len, from_tag.s);

				if(send_esct(msg, callid_orig, from_tag) == 0){
					LM_ERR("error in send to esct\n");
				}

				hash_code= core_hash(&callid_event, 0, subst_size);
				LM_DBG("********************************************HASH_CODE%d\n", hash_code);

				delete_shtable(subs_htable, hash_code, cell_subs);

				/* Reply OK to Notify*/
				if(!eme_tm.t_reply(msg,200,&msg200)){
					LM_ERR("t_reply (200)\n");
					return 0;
				}
				return 1;

			}else{
				LM_ERR("INCOMPATIBLE RECEIVED STATUS\n");
				if(!eme_tm.t_reply(msg,400,&msg400)){
					LM_ERR("t_reply (400)\n");
				}
				return 0;
			}
		}
	}

	LM_DBG("STATUS: %d \n ", cell_subs->dlg_id->status);
	LM_DBG(" --- NOTIFY BODY %s", msg->eoh);

	notify_body = parse_notify(msg->eoh);
	if( notify_body == NULL){
		LM_ERR("invalid body in Notify request\n");
		if(!eme_tm.t_reply(msg,400,&msg400)){
			LM_ERR("t_reply (400)\n");
		}
		resp = 0;
		goto end;
	}

	version_init = strchr(notify_body->params->version,'\"');
	version_init++;
	version_end = strchr(version_init,'\"');
	size_version = version_end - version_init;
	version_aux = pkg_malloc(size_version + 1);
	if (version_aux == NULL) {
		LM_ERR("no more pkg memory\n");
		return 0;
	}
	memcpy(version_aux, version_init, size_version );
	version_aux[size_version] = '\0';
	version = atoi(version_aux);
	pkg_free(version_aux);
	LM_DBG(" --- STATE %s", notify_body->state);
	LM_DBG(" --- VERSION %d", version);

	/* Reply OK to Notify*/
	if(!eme_tm.t_reply(msg,200,&msg200)){
		LM_DBG("t_reply (200)\n");
		free_parsed_notify(notify_body);
		resp = 0;
		goto end;
	}

	if(cell_subs->version >= version){
		LM_ERR(" --- ERRO IN VERSION PARAMETER IN NOTIFY BODY");
		free_parsed_notify(notify_body);
		resp = 0;
		goto end;
	}else{
		cell_subs->version  = version;
	}


	/* if Notify body state has terminated value, which indicates that emergency call finish,
	   then send subscribe with expire=0 to terminate the subscriber dialog*/
	if(strcmp(notify_body->state, "terminated") == 0){
		expires = 0;
		LM_DBG(" --- STATE %s", notify_body->state);
		if(send_subscriber_within(msg, cell_subs, expires) == -1){
			LM_ERR(" --- Error in send subscriber terminated \n");
		}
	}

	resp = 1;
	free_parsed_notify(notify_body);

end:
	pkg_free(subs_state);
	pkg_free(subs_expires);
	return resp;
}
Пример #28
0
/* look for subscriber cell using callid and to_tag of Notify*/
struct sm_subscriber* get_subs_cell(struct sip_msg *msg, str callid_event) {
	str callid;
	str method;
	struct to_body *pto= NULL, *pfrom = NULL;
	struct sm_subscriber* s;
	unsigned int hash_code;

	method.s = msg->first_line.u.request.method.s;
	method.len = msg->first_line.u.request.method.len;

	if ( parse_headers(msg,HDR_EOH_F, 0) == -1 ){
		LM_ERR("error in parsing headers\n");
		return NULL;
	}

	// get callid from Notify
	if( msg->callid==NULL || msg->callid->body.s==NULL){
		LM_ERR("reply without callid header\n");
		return NULL;
	}
	callid = msg->callid->body;
	LM_DBG("CALLID: %.*s \n ", callid.len, callid.s );

	if (msg->from->parsed == NULL){
		if ( parse_from_header( msg )<0 ){
			LM_ERR("reply without From header\n");
			return NULL;
		}
	}

	//get From header from Notify
	pfrom = get_from(msg);
	LM_DBG("PFROM: %.*s \n ", pfrom->uri.len, pfrom->uri.s );

	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0){
		LM_ERR("reply without tag value \n");
		return NULL;
	}
	if( msg->to==NULL || msg->to->body.s==NULL){
		LM_ERR("error in parse TO header\n");
		return NULL;
	}

	// get To header from Notify
	pto = get_to(msg);
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		return NULL;
	}
	if( pto->tag_value.s ==NULL || pto->tag_value.len == 0){
		LM_ERR("reply without tag value \n");
	}
	LM_DBG("PTO: %.*s \n ", pto->uri.len, pto->uri.s );
	LM_DBG("PTO_TAG: %.*s \n ", pto->tag_value.len, pto->tag_value.s );
	LM_DBG("********************************************CALLID_STR%.*s\n", callid_event.len, callid_event.s);
	hash_code= core_hash(&callid_event, 0, subst_size);
	LM_DBG("********************************************HASH_CODE%d\n", hash_code);



	s= search_shtable(subs_htable, &callid, &pfrom->tag_value, hash_code, &method);
	if (s == NULL) {
		LM_ERR(" ---FAILURE SUB_CELL NOT FOUND IN SHTABLE\n");
	}

	return s;
}
Пример #29
0
/*Create cell to control Subscriber Dialog States
  This cell save this information:
  - Dialog Id:
  .Callid
  .rem_tag
  .local_tag
  - expires
  - Local_uri
  - Remote_uri
  - Notifier_uri
  - INVITE's Callid
  - Event body
  - State
  */
int create_subscriber_cell(struct sip_msg* reply, struct parms_cb* params_cb){

	str* callid = NULL;
	int expires= 0;
	struct to_body *pto= NULL, *pfrom = NULL;
	int size_subs_cell;
	int vsp_addr_len;
	char *vsp_addr = "@vsp.com";
	time_t rawtime;
	int time_now;
	struct sm_subscriber *subs_cell = NULL;
	char *p;
	unsigned int hash_code;

	callid= (str*) pkg_malloc (sizeof (str));
	if (callid == NULL) {
		LM_ERR("--------------------------------------------------no more pkg memory\n");
		return 0;
	}
	/*Verify repĺy is OK and get callid and expires from response*/
	if ( !extract_reply_headers(reply, callid, expires)){
		LM_ERR("fail in extract headers\n");
		pkg_free(callid);
		return 0;
	}

	/*get From header fields */
	pfrom = get_from(reply);
	LM_DBG("PFROM: %.*s \n ", pfrom->uri.len, pfrom->uri.s );
	if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0){
		LM_ERR("reply without tag value \n");
		pkg_free(callid);
		return 0;
	}

	/*get To header fields */
	pto = get_to(reply);
	LM_DBG("PTO: %.*s \n ", pto->uri.len, pto->uri.s );
	if (pto == NULL || pto->error != PARSE_OK) {
		LM_ERR("failed to parse TO header\n");
		pkg_free(callid);
		return 0;
	}

	// get source ip address that send INVITE
	vsp_addr = ip_addr2a(&reply->rcv.src_ip);
	vsp_addr_len = strlen(vsp_addr);

	time(&rawtime);
	time_now = (int)rawtime;
	LM_DBG("TIME : %d \n", (int)rawtime );

	/* build subscriber cell */
	size_subs_cell = sizeof (struct sm_subscriber) + (2 * sizeof(struct dialog_id))
		+ callid->len + pfrom->tag_value.len + pto->tag_value.len + pfrom->uri.len + pto->uri.len
		+ params_cb->callid_ori.len +  params_cb->event.len + params_cb->from_tag.len + vsp_addr_len + 9 ;
	subs_cell = pkg_malloc(size_subs_cell + 1);
	if (!subs_cell) {
		LM_ERR("no more shm\n");
		return 0;
	}

	memset(subs_cell, 0, size_subs_cell + 1);
	subs_cell->expires = expires;
	subs_cell->timeout =  TIMER_N + time_now;
	LM_DBG("SUBS_TIMEOUT: %d \n ", subs_cell->timeout );
	subs_cell->version =  -1;

	subs_cell->dlg_id = (struct dialog_id*)(subs_cell + 1);

	subs_cell->dlg_id->callid.len = callid->len;
	subs_cell->dlg_id->callid.s = (char *) (subs_cell->dlg_id + 1);
	memcpy(subs_cell->dlg_id->callid.s, callid->s, callid->len);
	LM_DBG("SUBS_CALLID: %.*s \n ", subs_cell->dlg_id->callid.len, subs_cell->dlg_id->callid.s );

	subs_cell->dlg_id->local_tag.len = pfrom->tag_value.len;
	subs_cell->dlg_id->local_tag.s = (char *) (subs_cell->dlg_id + 1) + callid->len;
	memcpy(subs_cell->dlg_id->local_tag.s, pfrom->tag_value.s, pfrom->tag_value.len);
	LM_DBG("SUBS_FROM_TAG: %.*s \n ", subs_cell->dlg_id->local_tag.len, subs_cell->dlg_id->local_tag.s );

	subs_cell->dlg_id->rem_tag.len = pto->tag_value.len;
	subs_cell->dlg_id->rem_tag.s = (char *) (subs_cell->dlg_id + 1) + callid->len + pfrom->tag_value.len;
	memcpy(subs_cell->dlg_id->rem_tag.s, pto->tag_value.s, pto->tag_value.len);
	LM_DBG("SUBS_TO_TAG: %.*s \n ", subs_cell->dlg_id->rem_tag.len, subs_cell->dlg_id->rem_tag.s );

	p = (char *)(subs_cell->dlg_id + 1) + callid->len + pfrom->tag_value.len + pto->tag_value.len;
	subs_cell->call_dlg_id = (struct dialog_id*)p;

	subs_cell->call_dlg_id->callid.len= params_cb->callid_ori.len;
	subs_cell->call_dlg_id->callid.s = (char *) (subs_cell->call_dlg_id + 1);
	memcpy(subs_cell->call_dlg_id->callid.s, params_cb->callid_ori.s, params_cb->callid_ori.len);
	LM_DBG("SUBS_CALLID_ORI: %.*s \n ", subs_cell->call_dlg_id->callid.len, subs_cell->call_dlg_id->callid.s );

	subs_cell->call_dlg_id->local_tag.len= params_cb->from_tag.len;
	subs_cell->call_dlg_id->local_tag.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len;
	memcpy(subs_cell->call_dlg_id->local_tag.s, params_cb->from_tag.s, params_cb->from_tag.len);
	LM_DBG("SUBS_FROMTAG_event: %.*s \n ", subs_cell->call_dlg_id->local_tag.len, subs_cell->call_dlg_id->local_tag.s );

	subs_cell->loc_uri.len = pfrom->uri.len;
	subs_cell->loc_uri.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len;
	memcpy(subs_cell->loc_uri.s,pfrom->uri.s,pfrom->uri.len);
	LM_DBG("SUBS_LOC_URI: %.*s \n ", subs_cell->loc_uri.len, subs_cell->loc_uri.s );

	subs_cell->rem_uri.len= pto->uri.len;
	subs_cell->rem_uri.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len + pfrom->uri.len;
	memcpy(subs_cell->rem_uri.s, pto->uri.s, pto->uri.len);
	LM_DBG("SUBS_REM_URI: %.*s \n ", subs_cell->rem_uri.len, subs_cell->rem_uri.s );

	subs_cell->event.len= params_cb->event.len;
	subs_cell->event.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len + pfrom->uri.len + pto->uri.len;
	memcpy(subs_cell->event.s, params_cb->event.s, params_cb->event.len);
	LM_DBG("SUBS_EVENT: %.*s \n ", subs_cell->event.len, subs_cell->event.s );

	subs_cell->contact.len = vsp_addr_len + 9;
	subs_cell->contact.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len + pfrom->uri.len + pto->uri.len + params_cb->event.len;
	memcpy(subs_cell->contact.s, "sip:test@", 9);
	memcpy(subs_cell->contact.s + 9, vsp_addr, vsp_addr_len);
	LM_DBG("SUBS_CONTACT: %.*s \n ", subs_cell->contact.len, subs_cell->contact.s );

	subs_cell->dlg_id->status = NOTIFY_WAIT;

	hash_code= core_hash(&subs_cell->dlg_id->callid, 0, subst_size);
	LM_DBG("********************************************HASH_CODE%d\n", hash_code);


	if(insert_shtable(subs_htable, hash_code,subs_cell) == NULL){
		LM_ERR("inserting new record in subs_htable\n");
	}

	pkg_free(subs_cell);
	pkg_free(callid);

	return 1;

}
Пример #30
0
void unlock_contact_slot(str* contact_uri) {
    unsigned int sl;
    sl = core_hash(contact_uri, 0, contact_list->size);

    unlock_contact_slot_i(sl);
}