/**
 * Updates the r_contact with the new security values.
 * @param host - the host part of the contact, in string
 * @param port - the port number of the contact
 * @param transport - the transport of the contact
 * @param uri - URI of the contact
 * @param reg_state - Registration state
 * @param expires - expires in
 * @param ipsec - the new IPSec tunnel
 * @returns the newly added r_public, 0 on error
 */
r_contact* update_r_contact_sec(str host,int port,int transport,
	str *uri,enum Reg_States *reg_state,int *expires,
	r_security *s, int * sos_reg)
{
	r_contact *c = NULL;
	r_reg_type sos_mask =  NORMAL_REG;
	
	if(sos_reg && (*sos_reg)>0){
			LOG(L_DBG,"DBG:"M_NAME":update_r_contact_sec: with sos uri param\n");
			sos_mask = EMERG_REG;
	}
	
	c = get_r_contact(host,port,transport, sos_mask);
	if (!c){
		if (uri&&reg_state){
			c = add_r_contact(host,port,transport,*uri,*reg_state,*expires,(str*) 0,0,0,sos_mask);
			c->security_temp = s;
			r_unlock(c->hash);
			return c;
		}
		else return 0;
	}else{
		if (c->security_temp){
			P_security_drop(c,c->security_temp);
			free_r_security(c->security_temp);
		}		
		c->security_temp = s;
		c->sos_flag = sos_mask;
		r_unlock(c->hash);
		return c;
	}
}
示例#2
0
/**
 * Updates the r_contact with the new expires, ua valu, path value.
 * \note If not found it is added
 * \note Must be called with a lock on the hash slot to avoid races
 * @param p - the r_public to add to
 * @param uri - the contact uri
 * @param expires - new expires value, NULL if not necessary
 * @param ua - new user agent string, NULL if no update necessary
 * @param path - Path header received at registration
 * @returns the updated r_contact or NULL on error
 */
r_contact* update_r_contact(r_public *p,str uri,int *expires, str *ua,str *path)
{
	r_contact *c;
	
	if (!p) return 0;
	c = get_r_contact(p,uri);
	if (!c){
		if (expires && ua && path)
			return add_r_contact(p,uri,*expires,*ua,*path);
		else return 0;
	}else{
		if (expires) c->expires = *expires;
		if (ua){
			if (c->ua.s) shm_free(c->ua.s);
			c->ua.s = shm_malloc(ua->len);
			if (!c->ua.s) {
				LOG(L_ERR,"ERR:"M_NAME":update_r_contact(): Error allocating %d bytes\n",
					ua->len);
				c->ua.len=0;
				return 0;
			}
			c->ua.len = ua->len;
			memcpy(c->ua.s,ua->s,ua->len);
		}
		if (path){
			if (c->path.s) shm_free(c->path.s);
			c->path.s = shm_malloc(path->len);
			if (!c->path.s) {
				LOG(L_ERR,"ERR:"M_NAME":update_r_contact(): Error allocating %d bytes\n",
					path->len);
				c->path.len=0;
				return 0;
			}
			c->path.len = path->len;
			memcpy(c->path.s,path->s,path->len);
		}
		return c;
	}
}
/**
 * Updates the r_contact with the new states
 * If not found, it will be inserted
 * \note Aquires the lock on the hash_slot on success, so release it when you are done.
 * @param host - the host part of the contact, in string
 * @param port - the port number of the contact
 * @param transport - the transport of the contact
 * @param uri - URI of the contact
 * @param reg_state - Registration state
 * @param expires - expires in
 * @param service_route - array of service routes
 * @param service_route_cnt - the size of the array above
 * @param pinhole - NAT pin hole
 * @param sos_flag - flag for Emergency Registration
 * @returns the updated added r_contact, 0 on error
 */
r_contact* update_r_contact(str host,int port,int transport,
	str *uri,enum Reg_States *reg_state,int *expires,str **service_route,
	int *service_route_cnt, r_nat_dest **pinhole, int *sos_flag)
{
	r_contact *c=0;
	int i;
	r_reg_type sos_mask;

	if(sos_flag && (*sos_flag>0))
		sos_mask = EMERG_REG;
	else	sos_mask = NORMAL_REG;

	c = get_r_contact(host,port,transport, sos_mask);
	if (!c){
		if (uri&&reg_state && expires && service_route && service_route_cnt)
			return pinhole?add_r_contact(host,port,transport,*uri,*reg_state,*expires,*service_route,*service_route_cnt, *pinhole, sos_mask):
					   add_r_contact(host,port,transport,*uri,*reg_state,*expires,*service_route,*service_route_cnt, 0,  sos_mask);
		else return 0;
	}else{
		/* first drop the old temporary public ids */
		if (c->reg_state==DEREGISTERED && reg_state && *reg_state==REGISTERED){
			while(c->head){
				del_r_public(c,c->head);
			}
		}

		if (uri) {
			if (c->uri.s) shm_free(c->uri.s);
			STR_SHM_DUP(c->uri,*uri,"update_r_contact");
		}
		if (reg_state) c->reg_state = *reg_state;
		if (expires) c->expires = *expires;
		if (service_route){
			if (c->service_route){
				for(i=0;i<c->service_route_cnt;i++)
					if (c->service_route[i].s) shm_free(c->service_route[i].s);
				shm_free(c->service_route);
				c->service_route=0;
				c->service_route_cnt=0;
			}
			if (*service_route&&*service_route_cnt){
				c->service_route = shm_malloc((*service_route_cnt)*sizeof(str));
				if (!c->service_route){
					LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
						(*service_route_cnt)*sizeof(str));					
					goto out_of_memory;					
				}else{
					for(i=0;i<*service_route_cnt;i++)
						STR_SHM_DUP(c->service_route[i],(*service_route)[i],"new_r_contact");
					c->service_route_cnt = *service_route_cnt;											
				}			
			}
		}
		if (pinhole) c->pinhole = *pinhole;
		c->sos_flag = sos_mask;
		return c;
	}
	
out_of_memory:
	return c;	
}