示例#1
0
static void find_and_delete_dialog(ua_pres_t *dialog, int hash_code)
{
	ua_pres_t *presentity;

	if (dbmode == PUA_DB_ONLY)
	{
		delete_dialog_puadb(dialog);
	}
	else
	{
		lock_get(&HashT->p_records[hash_code].lock);
 		presentity= get_dialog(dialog, hash_code);
		if (presentity == NULL)
		{
			presentity = get_temporary_dialog(dialog, hash_code);
			if(presentity== NULL)
			{
				LM_ERR("no record found\n");
				lock_release(&HashT->p_records[hash_code].lock);
				return;
			}
		}

		delete_htable(presentity, hash_code);
		lock_release(&HashT->p_records[hash_code].lock);
	}
}
示例#2
0
文件: pua.c 项目: kiryu/kamailio
static void hashT_clean(unsigned int ticks,void *param)
{
	int i;
	time_t now;
	ua_pres_t* p= NULL, *q= NULL;

	if (dbmode==PUA_DB_ONLY) 
	{
		clean_puadb(update_period, min_expires );
		return;
	}

	now = time(NULL);
	for(i= 0;i< HASH_SIZE; i++)
	{
		lock_get(&HashT->p_records[i].lock);
		p= HashT->p_records[i].entity->next;
		while(p)
		{	
			print_ua_pres(p);
			if(p->expires- update_period < now )
			{
				if((p->desired_expires> p->expires + min_expires) || 
						(p->desired_expires== 0 ))
				{
					if(update_pua(p)< 0)
					{
						LM_ERR("while updating record\n");
						lock_release(&HashT->p_records[i].lock);
						return;
					}
					p= p->next;
					continue;
				}	
				if(p->expires < now - 10)
				{
					q= p->next;
					LM_DBG("Found expired: uri= %.*s\n", p->pres_uri->len,
							p->pres_uri->s);
					delete_htable(p, i);
					p= q;
				}
				else
					p= p->next;
			}	
			else
				p= p->next;
		}
		lock_release(&HashT->p_records[i].lock);
	}


}
示例#3
0
文件: hash.c 项目: mattvv/kamailio
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;
}
示例#4
0
static void find_and_delete_record(ua_pres_t *dialog, int hash_code)
{
	ua_pres_t *presentity;

	if (dbmode == PUA_DB_ONLY)
	{
		delete_record_puadb(dialog);
	}
	else
	{
		lock_get(&HashT->p_records[hash_code].lock);
		presentity = search_htable(dialog, hash_code);
		if (presentity == NULL)
		{
			LM_DBG("Record found in table and deleted\n");
			lock_release(&HashT->p_records[hash_code].lock);
			return;
		}
		delete_htable(presentity, hash_code);
		lock_release(&HashT->p_records[hash_code].lock);
	}
}
示例#5
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;
}
示例#6
0
void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps)
{
	struct hdr_field* hdr= NULL;
	struct sip_msg* msg= NULL;
	ua_pres_t* presentity= NULL;
	unsigned int lexpire= 0;
	str etag;
	unsigned int hash_index, local_index;
	unsigned long pres_id;

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

	msg= ps->rpl;
	if(msg == NULL)
	{
		LM_ERR("no reply message found\n");
		return;
	}
	LM_DBG("cback param = %lu\n", (unsigned long)*ps->param);

	pres_id = (unsigned long)*ps->param;
	PUA_PARSE_PRES_ID(pres_id, hash_index, local_index);
	LM_DBG("hash_index= %u, local_index= %u\n", hash_index, local_index);

	if(!find_htable(hash_index, local_index))
	{
		LM_ERR("No record found\n");
		return;
	}

	if(msg== FAKED_REPLY)
	{
		LM_DBG("FAKED_REPLY\n");
		goto done;
	}

	if( ps->code>= 300 )
	{
		delete_htable(hash_index, local_index);
		goto done;
	}

	if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
	{
		LM_ERR("parsing headers\n");
		return;
	}
	if(msg->expires== NULL || msg->expires->body.len<= 0)
	{
		LM_ERR("No Expires header found\n");
		return;
	}
	if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
	{
		LM_ERR("cannot parse Expires header\n");
		return;
	}
	lexpire = ((exp_body_t*)msg->expires->parsed)->val;
	LM_DBG("lexpire= %u\n", lexpire);

	if(lexpire == 0)
	{
		delete_htable(hash_index, local_index);
		goto done;
	}
	hdr = get_header_by_static_name( msg, "SIP-ETag");
	if( hdr==NULL ) /* must find SIP-Etag header field in 200 OK msg*/
	{
		LM_ERR("no SIP-ETag header field found\n");
		return;
	}
	etag= hdr->body;

	update_htable(hash_index, local_index, lexpire, &etag, 0);

done:
	lock_get(&HashT->p_records[hash_index].lock);
	presentity = get_htable_safe(hash_index, local_index);
	if(!presentity)
	{
		LM_DBG("Record not found\n");
		lock_release(&HashT->p_records[hash_index].lock);
		return;
	}

	if(presentity->ua_flag == REQ_OTHER)
	{
		run_pua_callbacks(presentity, msg);
		presentity->cb_param = NULL;
	}
	presentity->waiting_reply = 0;
	while(presentity->pending_publ)
	{
		publ_t* pending_publ = presentity->pending_publ;
		publ_info_t* publ = construct_pending_publ(presentity);
		if(publ == NULL)
		{
			LM_ERR("Failed to create publish record\n");
			lock_release(&HashT->p_records[hash_index].lock);
			presentity->pending_publ = pending_publ->next;
			shm_free(pending_publ);
			continue;
		}
		LM_DBG("Found pending publish\n");
		presentity->pending_publ  = 0;
		presentity->waiting_reply = 1;
		send_publish_int(presentity, publ, get_event(presentity->event),
				presentity->hash_index);
		pkg_free(publ);
		presentity->pending_publ = pending_publ->next;
		shm_free(pending_publ);
		break;
	}

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