/** * 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; }
/** * 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; }