/**
 * Searches for a r_contact contact and returns it.
 * \note Will lock the hash_slot if found! So release it when you are done!
 * @param host - the IP in string format
 * @param port - the port number
 * @param transport - the transport type
 * @param sos_mask - type of registration
 * @returns - the r_contact found, 0 if not found
 */
r_contact* get_r_contact(str host,int port,int transport, r_reg_type sos_mask)
{
	r_contact *c=0;
	unsigned int hash;
	if (!registrar) return 0;
	hash = get_contact_hash(host,port,transport,r_hash_size);
	r_lock(hash);
	c = registrar[hash].head;
	while(c){
		if (c->port == port &&
			(c->sos_flag & sos_mask) && 
//			c->transport == transport && /* because xten doesn't care about protocols */ 
			c->host.len == host.len &&
			strncasecmp(c->host.s,host.s,host.len)==0) return c;
		c = c->next;
	}
	r_unlock(hash);
	return 0;
}
/**
 * Creates a registrar contact 
 * This does not insert it in the registrar
 * @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
 * @returns the new r_contact* or NULL on error
 */
r_contact* new_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_reg_type sos_flag)
{
	r_contact *c;
	int i;
	
	c = shm_malloc(sizeof(r_contact));
	if (!c) {
		LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
			sizeof(r_contact));
		goto error;
	}
	memset(c,0,sizeof(r_contact));
	
	STR_SHM_DUP(c->host,host,"new_r_contact");
	c->port = port;
	c->transport = transport;
	c->hash = get_contact_hash(host,port,transport,r_hash_size);
	STR_SHM_DUP(c->uri,uri,"new_r_contact");		
	c->reg_state = reg_state;
	c->expires = expires;	
	c->sos_flag = sos_flag;
		
	if (service_route_cnt && service_route){
		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 error;
		}
		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;
	}
		
	return c;
error:
out_of_memory:
	if (c){
		free_r_contact(c);			
	}
	return 0;
}
Beispiel #3
0
/**
 *	Decode a r_contact from a binary data structure
 * @param x - binary data to decode from
 * @returns the r_contact* where the data has been decoded
 */
r_contact* bin_decode_r_contact(bin_data *x)
{
	r_contact *c=0;
	r_public *p=0,*pn=0;
	int len,i;
	char k;
	unsigned short us;
	str st;
	
	len = sizeof(r_contact);
	c = (r_contact*) shm_malloc(len);
	if (!c) {
		LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error allocating %d bytes.\n",len);
		goto error;
	}
	memset(c,0,len);
	
	if (!bin_decode_str(x,&st)||!str_shm_dup(&(c->host),&st)) goto error;
	if (!bin_decode_ushort(x,&c->port)) goto error;
	if (!bin_decode_char(x,&c->transport)) goto error;

	c->hash = get_contact_hash(c->host,c->port,c->transport,r_hash_size);
	
	if (!bin_decode_r_security(x,&(c->security_temp))) goto error;
	if (!bin_decode_r_security(x,&(c->security))) goto error;
	
	if (!bin_decode_str(x,&st)||!str_shm_dup(&(c->uri),&st)) goto error;
	
	if (!bin_decode_char(x,&k)) goto error;
	c->reg_state = k;

	if (!bin_decode_time_t(x,&c->expires)) goto error;
	
	if (!bin_decode_ushort(x,	&c->service_route_cnt)) goto error;

	len = sizeof(str)*c->service_route_cnt;
	c->service_route = (str*) shm_malloc(len);
	if (!c->service_route) {
		LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error allocating %d bytes.\n",len);
		goto error;
	}
	memset(c->service_route,0,len);	
	for(i=0;i<c->service_route_cnt;i++)
		if (!bin_decode_str(x,&st)||!str_shm_dup(c->service_route+i,&st)) goto error;
	
	if (!bin_decode_pinhole(x,&(c->pinhole ))) goto error;
	
	if (!bin_decode_char(x,&k)) goto error;
	c->sos_flag = k;
	
	if (!bin_decode_str(x,&st)||!str_shm_dup(&(c->pcc_session_id),&st)) goto error;
		
	if (!bin_decode_ushort(x,&us)) goto error;
	for(i=0;i<us;i++){
		p = bin_decode_r_public(x);
		if (!p) goto error;
		p->prev = c->tail;
		p->next = 0;
		if (c->tail) c->tail->next = p;
		c->tail = p;
		if (!c->head) c->head = p;
	}
	return c;
error:
	LOG(L_ERR,"ERR:"M_NAME":bin_decode_r_contact: Error while decoding (at %d (%04x)).\n",x->max,x->max);
	if (c) {
		if (c->host.s) shm_free(c->host.s);		
		if (c->security_temp) free_r_security(c->security_temp);
		if (c->security) free_r_security(c->security);
		if (c->uri.s) shm_free(c->uri.s);
		if (c->pinhole) shm_free(c->pinhole);
		while(c->head){
			p = c->head;
			pn = p->next;
			free_r_public(p);
			c->head = pn;
		}
		shm_free(c);
	}
	return 0;
}