コード例 #1
0
ファイル: registrar_storage.c プロジェクト: asyn/openvims
/**
 * Updates the r_subscriber with the new expires value
 * If not found, it will be inserted
 * @param p - the r_public to add to
 * @param subscriber - the subscriber to update
 * @param expires - new expires value, NULL if not necessary
 * @param ua - new user agent string, NULL if no update necessary
 * @param dialog - dialog for the subscription
 * @returns the newly added r_public, 0 on error
 */
r_subscriber* update_r_subscriber(r_public *p,str subscriber,int event,int* expires,dlg_t *dialog)
{
	r_subscriber *s;
	
	if (!p) return 0;
	s = get_r_subscriber(p,subscriber,event);
	if (!s){
		if (expires)
			return add_r_subscriber(p,subscriber,event,*expires,dialog);
		else return 0;
	}else{
		if (expires) s->expires = *expires;
		if (s->dialog && s->dialog!=dialog) tmb.free_dlg(s->dialog);
		s->dialog = dialog;
		return s;
	}
}
コード例 #2
0
/**
 * Save this subscription.
 * @param msg - the SIP SUBSCRIBE message
 * @param str1 - not used
 * @param str2 - not used
 * @returns #CSCF_RETURN_TRUE if allowed, #CSCF_RETURN_FALSE if not, #CSCF_RETURN_ERROR on error
 */
int S_subscribe(struct sip_msg *msg,char *str1,char *str2)
{
	int ret=CSCF_RETURN_FALSE;
	struct sip_uri puri;
	str uri={0,0};
	str event;
	int event_i=IMS_EVENT_NONE;
	int expires=0,expires_time=0;
	str subscriber;
	r_public *p=0;
	r_subscriber *s=0,*new_s=0;
	dlg_t *dialog=0;

	LOG(L_DBG,"DBG:"M_NAME":S_subscribe: Saving SUBSCRIBE\n");

	/* First check the parameters */
	if (msg->first_line.type!=SIP_REQUEST)
	{
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: This message is not a request\n");
		goto error;
	}		
	if (msg->first_line.u.request.method.len != 9 ||
		memcmp(msg->first_line.u.request.method.s,"SUBSCRIBE",9)!=0)
	{
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: This message is not a SUBSCRIBE\n");
		goto error;
	}

	/* 1. Get the event 	*/
	event = cscf_get_event(msg);
	if (event.len!=3||strncasecmp(event.s,"reg",3)!=0){
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Accepting only <Event: reg>. Found: <%.*s>\n",
			event.len,event.s);
		ret = CSCF_RETURN_FALSE;	
		goto done;
	} 
	if (event.len==0 && strncasecmp(event.s,"reg",3)==0)
		event_i = IMS_EVENT_REG;
	
	/* 2. Get the target of the SUBSCRIBE from RequestURI */
	if (msg->new_uri.s) uri = msg->new_uri;
	else uri = msg->first_line.u.request.uri;
	
	if (parse_uri(uri.s, uri.len, &puri) < 0) {
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Error parsing uri <%.*s>\n",
			uri.len,uri.s);
		goto error;
	}
	uri.len = lookup_sip.len+puri.user.len+1+puri.host.len;
	uri.s = pkg_malloc(uri.len);
	if (!uri.s){
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Error allocating %d bytes\n",uri.len);
		goto error;
	}
	uri.len=0;
	memcpy(uri.s,lookup_sip.s,lookup_sip.len);
	uri.len+=lookup_sip.len;
	memcpy(uri.s+uri.len,puri.user.s,puri.user.len);
	uri.len+=puri.user.len;
	uri.s[uri.len++]='@';
	memcpy(uri.s+uri.len,puri.host.s,puri.host.len);
	uri.len+=puri.host.len;

	/* 3. Get the Subscriber's Identity */
	subscriber = cscf_get_contact(msg);
	if (!subscriber.len){
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Contact empty.\n");
		ret =  CSCF_RETURN_FALSE;
		goto done;		
	}
	LOG(L_DBG,"DBG:"M_NAME":S_subscribe: Contact <%.*s>.\n",
		subscriber.len,subscriber.s);
	
	p = get_r_public(uri);

	/* Registration is possible even if the user is not registered... so just create one */
	if (!p){
		p = add_r_public(uri,0,0);
	}
	if (!p){		
		LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Identity not found and error on creation <%.*s>\n",
			uri.len,uri.s);
		ret =  CSCF_RETURN_FALSE;
		goto done;
	}
		
	expires = cscf_get_expires_hdr(msg,0);
	if (expires == -1) expires = subscription_default_expires;
	if (expires > 0) {
		if (expires < subscription_min_expires) expires = subscription_min_expires;
		if (expires > subscription_max_expires) expires = subscription_max_expires;
		r_act_time();
		expires_time = expires + time_now;
		
		/* get the old subscriber - if any */
		s = get_r_subscriber(p,subscriber,event_i);	
		if (!s){
			/* create a new dialog */
			if (tmb.new_dlg_uas(msg, 200, &dialog) < 0) {		
				LOG(L_ERR,"ERR:"M_NAME":S_subscribe:  Error while creating dialog state\n");
				ret = CSCF_RETURN_FALSE;
				goto error;
			}
		}else
			dialog = s->dialog;
		
		/* update the subscriber */
		if ((new_s=update_r_subscriber(p,subscriber,event_i,&expires_time,dialog))!=0){		
			//if (!s)	/* Only on first subscription, not on refreshes, send a notify */
				S_event_reg(p,0,new_s,IMS_REGISTRAR_SUBSCRIBE,0);
			ret = CSCF_RETURN_TRUE;
		}
		else
			ret = CSCF_RETURN_FALSE;	
	}else{
		/* Unsubscribe */
		/* get the old subscriber - if any */
		r_act_time();
		s = get_r_subscriber(p,subscriber,event_i);	
		if (s) {
			s->expires = time_now;
			S_event_reg(p,0,s,IMS_REGISTRAR_UNSUBSCRIBE,1);
			del_r_subscriber(p,s);
		}
		ret = CSCF_RETURN_TRUE;
	}
done:	
	r_unlock(p->hash);
	if (expires ==0 )S_SUBSCRIBE_reply(msg,200,MSG_REG_UNSUBSCRIBE_OK,&expires,&uri);
	else S_SUBSCRIBE_reply(msg,200,MSG_REG_SUBSCRIBE_OK,&expires,&uri);
	if (uri.s) pkg_free(uri.s);
	return ret;
error:
	if (p) r_unlock(p->hash);
	if (uri.s) pkg_free(uri.s);
	ret=CSCF_RETURN_FALSE;
	return ret;	
}