registrar_storage.c File Reference


Detailed Description

Proxy-CSCF - Registrar Storage.

This is reversed registrar in the sense that contacts are pointing to public identities and not he other way around. This is required as the P-CSCF retrieves the identities based on the contacts. This being the operation most employed, it doesn't make sense to keep the registrar in the normal order.

The Registrar is kept as a hash table. If you have a large number of users, increase its size for better search times.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Definition in file registrar_storage.c.

#include <time.h>
#include "mod.h"
#include "registrar_storage.h"
#include "nat_helper.h"
#include "security.h"
#include "dlg_state.h"

Go to the source code of this file.

Defines

#define h_inc   h+=v^(v>>3)

Functions

void r_act_time ()
 Update the time.
int r_valid_contact (r_contact *c)
 Returns if a contact is valid.
int r_reg_contact (r_contact *c)
 Returns if a contact is valid and registered.
unsigned int get_contact_hash (str aor, int port, int transport, int hash_size)
 Computes the hash for a contact.
int r_storage_init (int hash_size)
 Initialize the registrar.
void r_storage_destroy ()
 Destroy the registrar.
void r_lock (unsigned int hash)
 Lock a registrar hash slot.
void r_unlock (unsigned int hash)
 UnLock a registrar hash slot.
r_publicnew_r_public (str aor, int is_default)
 Creates a registrar public record.
r_publicget_r_public (r_contact *c, str aor)
 Searches for a r_public record and returns it.
r_publicadd_r_public (r_contact *c, str aor, int is_default)
 Creates and Adds a new r_public record.
r_publicupdate_r_public (r_contact *c, str aor, int *is_default)
 Updates the r_public with the new is_default.
void del_r_public (r_contact *c, r_public *p)
 Drops and deallocates a r_public.
void free_r_public (r_public *p)
 Frees memory taken by a r_public aor structure.
r_ipsecnew_r_ipsec (int spi_uc, int spi_us, int spi_pc, int spi_ps, int port_uc, int port_us, str ealg_setkey, str r_ealg, str ck_esp, str alg_setkey, str r_alg, str ik_esp)
 Creates a registrar ipsec container.
void free_r_ipsec (r_ipsec *ipsec)
 Frees memory taken by a r_ipsec structure.
r_tlsnew_r_tls (int port_tls, unsigned long session_hash)
 Creates a registrar tls container.
void free_r_tls (r_tls *tls)
 Frees memory taken by a r_tls structure.
r_securitynew_r_security (str sec_header, r_security_type type, float q)
void free_r_security (r_security *s)
r_contactget_r_contact (str host, int port, int transport)
 Searches for a r_contact contact and returns it.
r_contactnew_r_contact (str host, int port, int transport, str uri, enum Reg_States reg_state, int expires, str *service_route, int service_route_cnt)
 Creates a registrar contact This does not insert it in the registrar.
r_contactadd_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)
 Creates and Adds a new r_contact.
r_contactupdate_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)
 Updates the r_contact with the new states If not found, it will be inserted.
r_contactupdate_r_contact_sec (str host, int port, int transport, str *uri, enum Reg_States *reg_state, int *expires, r_security *s)
 Updates the r_contact with the new security values.
r_nat_destget_r_nat_pinhole (str host, int port, int transport)
 Gets the contact structure with the uri the same as the one given.
void del_r_contact (r_contact *c)
 Drops and deallocates a r_contact.
void free_r_contact (r_contact *c)
 Frees memory taken by a r_contact structure.
void print_r (int log_level)
 Debug print the contents of the entire registrar.

Variables

time_t time_now
 Current time of the S-CSCF registrar.
r_hash_slotregistrar = 0
 The S-CSCF registrar.
int r_hash_size = 128
 Size of S-CSCF registrar hash table.


Define Documentation

#define h_inc   h+=v^(v>>3)


Function Documentation

void r_act_time (  )  [inline]

Update the time.

Definition at line 79 of file registrar_storage.c.

Referenced by get_r_public_expires(), P_security_200(), P_verify_security(), print_r(), print_subs(), r_assert_identity(), r_is_registered(), r_is_registered_id(), r_is_unregistered_id(), r_notification_process(), r_private_expire(), r_public_expire(), r_update_subscription_status(), registrar_timer(), S_event_reg(), S_lookup(), S_subscribe(), save_contact_security(), subscription_timer(), and update_contacts().

00080 {
00081     time_now=time(0);
00082 }

int r_valid_contact ( r_contact c  )  [inline]

Returns if a contact is valid.

Caller should do actualization of time_now

Parameters:
c - the contact to check
Returns:
1 if valid, else 0

Definition at line 90 of file registrar_storage.c.

Referenced by P_security_200(), P_verify_security(), r_is_registered_id(), r_is_unregistered_id(), r_update_subscription_status(), registrar_timer(), and S_lookup().

00091 {
00092 //  LOG(L_ERR,"%.*s -> %ld\n",c->uri.len,c->uri.s,c->expires-time_now);
00093     return (c->reg_state!=NOT_REGISTERED && c->reg_state!=DEREGISTERED)&&(c->expires>time_now);
00094 }

int r_reg_contact ( r_contact c  )  [inline]

Returns if a contact is valid and registered.

Caller should do actualization of time_now

Parameters:
c - the contact to check
Returns:
1 if valid, else 0

Definition at line 102 of file registrar_storage.c.

References _r_contact::expires, _r_contact::reg_state, REGISTERED, and time_now.

Referenced by r_assert_identity(), and r_is_registered().

00103 {
00104 //  LOG(L_ERR,"%.*s -> %ld\n",c->uri.len,c->uri.s,c->expires-time_now);
00105     return (c->reg_state==REGISTERED)&&(c->expires>time_now);
00106 }

unsigned int get_contact_hash ( str  aor,
int  port,
int  transport,
int  hash_size 
) [inline]

Computes the hash for a contact.

Parameters:
aor - the string of the contact
port - the port of the contact
transport - transport for the contact - ignored for now
hash_size - size of the hash, to % with
Returns:
the hash for the contact

Definition at line 116 of file registrar_storage.c.

References h_inc.

Referenced by bin_decode_r_contact(), get_r_contact(), and new_r_contact().

00117 {
00118 #define h_inc h+=v^(v>>3)
00119    char* p;
00120    register unsigned v;
00121    register unsigned h;
00122 
00123    h=0;
00124    for (p=aor.s; p<=(aor.s+aor.len-4); p+=4){
00125        v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
00126        h_inc;
00127    }
00128    v=0;
00129    for (;p<(aor.s+aor.len); p++) {
00130        v<<=8;
00131        v+=*p;
00132    }
00133    h_inc;
00134    v = port;
00135    h_inc;
00136 //   v = transport;
00137 //   h_inc;/* because xten does not care about transport */
00138 
00139    h=((h)+(h>>11))+((h>>13)+(h>>23));
00140    return (h)%hash_size;
00141 #undef h_inc 
00142 }

int r_storage_init ( int  hash_size  ) 

Initialize the registrar.

Parameters:
hash_size - number of hash slots to create
Returns:
1 if 0, 0 if not

Definition at line 149 of file registrar_storage.c.

Referenced by mod_init().

00150 {
00151     int i;
00152     r_hash_size = hash_size;
00153     
00154     registrar = shm_malloc(sizeof(r_hash_slot)*r_hash_size);
00155     memset(registrar,0,sizeof(r_hash_slot)*r_hash_size);
00156     
00157     for(i=0;i<r_hash_size;i++){
00158         registrar[i].lock = lock_alloc();
00159         if (!registrar[i].lock){
00160             LOG(L_ERR,"ERR:"M_NAME":r_storage_init(): Error creating lock\n");
00161             return 0;
00162         }
00163         registrar[i].lock = lock_init(registrar[i].lock);
00164     }
00165             
00166     if (!registrar) return 0;
00167     
00168     return 1;
00169 }

void r_storage_destroy (  ) 

Destroy the registrar.

Definition at line 174 of file registrar_storage.c.

Referenced by mod_destroy().

00175 {
00176     int i;
00177     r_contact *c,*nc;
00178     for(i=0;i<r_hash_size;i++){
00179         r_lock(i);
00180             c = registrar[i].head;
00181             while(c){
00182                 nc = c->next;
00183                 free_r_contact(c);
00184                 c = nc;
00185             }
00186         r_unlock(i);
00187         lock_dealloc(registrar[i].lock);
00188     }
00189     shm_free(registrar);    
00190 }

void r_lock ( unsigned int  hash  )  [inline]

Lock a registrar hash slot.

Parameters:
hash - index to lock

Definition at line 196 of file registrar_storage.c.

Referenced by add_r_contact(), add_r_public(), add_r_public_previous_lock(), bin_cache_dump_registrar_to_table(), bin_cache_load_registrar_from_table(), get_matching_wildcard_psi(), get_r_contact(), get_r_public(), get_r_public_previous_lock(), get_r_public_wpsi(), load_snapshot_registrar(), make_snapshot_registrar(), print_r(), r_private_expire(), r_storage_destroy(), and registrar_timer().

00197 {
00198 //  LOG(L_CRIT,"GET %d\n",hash);
00199     lock_get(registrar[hash].lock);
00200 //  LOG(L_CRIT,"GOT %d\n",hash);
00201 }

void r_unlock ( unsigned int  hash  )  [inline]

UnLock a registrar hash slot.

Parameters:
hash - index to unlock

Definition at line 206 of file registrar_storage.c.

Referenced by bin_cache_dump_registrar_to_table(), bin_cache_load_registrar_from_table(), Cx_PPA(), get_matching_wildcard_psi(), get_r_contact(), get_r_public(), get_r_public_expires(), get_r_public_previous_lock(), get_r_public_wpsi(), load_snapshot_registrar(), make_snapshot_registrar(), P_enforce_service_routes(), P_follows_service_routes(), P_NAT_relay(), P_security_200(), P_security_401(), P_security_relay(), P_verify_security(), print_r(), r_assert_identity(), r_get_reginfo_full(), r_is_integrity_protected(), r_is_not_registered_id(), r_is_registered(), r_is_registered_id(), r_is_unregistered_id(), r_notification_process(), r_public_expire(), r_storage_destroy(), registrar_timer(), S_add_p_asserted_identity(), S_add_p_charging_function_addresses(), S_assign_server(), S_is_authorized(), S_is_barred(), S_lookup(), S_subscribe(), update_contacts(), update_r_contact_sec(), and update_r_public().

00207 {
00208 //  LOG(L_CRIT,"REL %d\n",hash);    
00209     lock_release(registrar[hash].lock);
00210 }

r_public* new_r_public ( str  aor,
int  is_default 
)

Creates a registrar public record.

This does not insert it in the registrar

Parameters:
aor - the public identity as address of record
is_default - if this is the default public id
Returns:
- the r_public created, NULL on error

Definition at line 219 of file registrar_storage.c.

Referenced by add_r_public(), and add_r_public_previous_lock().

00220 {
00221     r_public *p;
00222     
00223     p = shm_malloc(sizeof(r_public));
00224     if (!p){
00225         LOG(L_ERR,"ERR:"M_NAME":new_r_public(): Unable to alloc %d bytes\n",
00226             sizeof(r_public));
00227         goto error;
00228     }   
00229     memset(p,0,sizeof(r_public));
00230         
00231     p->aor.s = shm_malloc(aor.len);
00232     if (!p->aor.s){
00233         LOG(L_ERR,"ERR:"M_NAME":new_r_public(): Unable to alloc %d bytes\n",
00234             aor.len);
00235         goto error;
00236     }
00237     p->aor.len = aor.len;
00238     memcpy(p->aor.s,aor.s,aor.len);
00239     
00240     p->is_default = is_default;
00241     
00242         
00243     return p;
00244 error:
00245     if (p){
00246         if (p->aor.s) shm_free(p->aor.s);   
00247         shm_free(p);
00248     }
00249     return 0;   
00250 }

r_public* get_r_public ( r_contact c,
str  aor 
)

Searches for a r_public record and returns it.

Note:
Must be called with a lock on the domain to avoid races
Parameters:
c - the r_contact to look into
aor - the address of record to look for
Returns:
- the r_public found, 0 if not found

Definition at line 259 of file registrar_storage.c.

Referenced by get_r_public_expires(), r_get_reginfo_full(), r_is_not_registered_id(), r_is_registered_id(), r_is_unregistered_id(), r_public_expire(), S_add_p_asserted_identity(), S_add_p_charging_function_addresses(), S_assign_server(), S_can_subscribe(), S_is_authorized(), S_is_barred(), S_lookup(), S_subscribe(), and update_r_public().

00260 {
00261     r_public *p=0;
00262     if (!c) return 0;
00263     p = c->head;
00264     while(p){
00265         if (p->aor.len == aor.len &&
00266             strncasecmp(p->aor.s,aor.s,aor.len)==0) return p;
00267         p = p->next;
00268     }
00269     return 0;
00270 }

r_public* add_r_public ( r_contact c,
str  aor,
int  is_default 
)

Creates and Adds a new r_public record.

Note:
Must be called with a lock on the domain to avoid races

When calling be sure that get_r_public(d,aor) returns 0, to avoid unreachable duplicates

Parameters:
c - the r_contact to add to
aor - the address of record
is_default - if this is the default contact
Returns:
the newly added r_public, 0 on error

Definition at line 283 of file registrar_storage.c.

Referenced by S_subscribe(), and update_r_public().

00284 {
00285     r_public *p;
00286     if (!c) return 0;
00287     p = new_r_public(aor,is_default);
00288     if (!p) return 0;
00289     p->next=0;
00290     p->prev=c->tail;
00291     if (c->tail) c->tail->next = p;
00292     c->tail = p;
00293     if (!c->head) c->head=p;
00294     
00295     return p;
00296 }

r_public* update_r_public ( r_contact c,
str  aor,
int *  is_default 
)

Updates the r_public with the new is_default.

If not found, it will be inserted

Note:
Must be called with a lock on the domain to avoid races
Parameters:
c - the r_contact to add to
aor - the address of record
is_default - if this is the default contact
Returns:
the newly added r_public, 0 on error

Definition at line 307 of file registrar_storage.c.

Referenced by Cx_PPA(), and update_contacts().

00308 {
00309     r_public *p;
00310 
00311     if (!c) return 0;
00312     p = get_r_public(c,aor);
00313     if (!p){
00314         if (is_default)
00315             return add_r_public(c,aor,*is_default);
00316         else return 0;
00317     }else{
00318         if (is_default) p->is_default = *is_default;
00319         return p;
00320     }
00321 }

void del_r_public ( r_contact c,
r_public p 
)

Drops and deallocates a r_public.

Note:
Must be called with a lock on the domain to avoid races

When calling be sure that get_r_public(d,aor) returns p, to avoid a bogus removal

Parameters:
c - the r_contact that this r_public is attached currently to
p - the r_public to remove

Definition at line 332 of file registrar_storage.c.

Referenced by registrar_timer(), and update_r_contact().

00333 {
00334     if (c->head == p) c->head = p->next;
00335     else p->prev->next = p->next;
00336     if (c->tail == p) c->tail = p->prev;
00337     else p->next->prev = p->prev;
00338     free_r_public(p);
00339 }

void free_r_public ( r_public p  ) 

Frees memory taken by a r_public aor structure.

Note:
Must be called with a lock on the domain to avoid races
Parameters:
p - the r_public to be deallocated

Definition at line 346 of file registrar_storage.c.

Referenced by bin_decode_r_contact(), del_r_public(), free_r_contact(), r_storage_destroy(), and update_r_public().

00347 {
00348     if (!p) return;
00349     if (p->aor.s) shm_free(p->aor.s);
00350     shm_free(p);
00351 }

r_ipsec* new_r_ipsec ( int  spi_uc,
int  spi_us,
int  spi_pc,
int  spi_ps,
int  port_uc,
int  port_us,
str  ealg_setkey,
str  r_ealg,
str  ck_esp,
str  alg_setkey,
str  r_alg,
str  ik_esp 
)

Creates a registrar ipsec container.

This does not insert it in the registrar the strings are duplicated in shm

Parameters:
spi_uc - SPI for UserEndpoint Client
spi_us - SPI for UserEndpoint Server
spi_pc - SPI for P-CSCF Client
spi_ps - SPI for UserEndpoint Server
port_uc - port for UserEndpoint Client
port_us - port for UserEndpoint Server
ealg_setkey - Cypher Algorithm
r_ealg - received Cypher Algorithm
ck_esp - Cypher Key
r_alg - received Integrity Algorithm
ik_esp - Integrity Key
Returns:
the new r_ipsec* container or NULL on error

Definition at line 370 of file registrar_storage.c.

References _r_ipsec::alg, _r_ipsec::ck, _r_ipsec::ealg, free_r_ipsec(), _r_ipsec::ik, M_NAME, _r_ipsec::port_uc, _r_ipsec::port_us, _r_ipsec::r_alg, _r_ipsec::r_ealg, _r_ipsec::spi_pc, _r_ipsec::spi_ps, _r_ipsec::spi_uc, _r_ipsec::spi_us, and STR_SHM_DUP.

Referenced by save_contact_security().

00372 {
00373     r_ipsec *ipsec;
00374     
00375     ipsec = shm_malloc(sizeof(r_ipsec));
00376     if (!ipsec) {
00377         LOG(L_ERR,"ERR:"M_NAME":new_r_ipsec(): Unable to alloc %d bytes\n",
00378             sizeof(r_ipsec));
00379         return 0;
00380     }
00381     memset(ipsec,0,sizeof(r_ipsec));
00382     
00383     ipsec->spi_uc = spi_uc;
00384     ipsec->spi_us = spi_us;
00385     ipsec->spi_pc = spi_pc;
00386     ipsec->spi_ps = spi_ps;
00387     ipsec->port_uc = port_uc;
00388     ipsec->port_us = port_us;
00389     
00390     
00391     STR_SHM_DUP(ipsec->ealg,ealg_setkey,"new_r_ipsec");
00392     STR_SHM_DUP(ipsec->r_ealg,r_ealg,"new_r_ipsec");
00393     STR_SHM_DUP(ipsec->alg,alg_setkey,"new_r_ipsec");
00394     STR_SHM_DUP(ipsec->r_alg,r_alg,"new_r_ipsec");
00395     STR_SHM_DUP(ipsec->ck,ck_esp,"new_r_ipsec");
00396     STR_SHM_DUP(ipsec->ik,ik_esp,"new_r_ipsec");
00397             
00398     return ipsec;
00399 out_of_memory:
00400     if (ipsec) free_r_ipsec(ipsec);
00401     return 0;   
00402 }

void free_r_ipsec ( r_ipsec ipsec  ) 

Frees memory taken by a r_ipsec structure.

Note:
Must be called with a lock on the domain to avoid races
Parameters:
ipsec - the r_public to be deallocated

Definition at line 409 of file registrar_storage.c.

References _r_ipsec::alg, _r_ipsec::ck, _r_ipsec::ealg, _r_ipsec::ik, _r_ipsec::r_alg, and _r_ipsec::r_ealg.

Referenced by bin_decode_r_security(), free_r_security(), and new_r_ipsec().

00410 {
00411     if (!ipsec) return;
00412     if (ipsec->ealg.s) shm_free(ipsec->ealg.s);
00413     if (ipsec->r_ealg.s) shm_free(ipsec->r_ealg.s);
00414     if (ipsec->alg.s) shm_free(ipsec->alg.s);
00415     if (ipsec->r_alg.s) shm_free(ipsec->r_alg.s);
00416     if (ipsec->ck.s) shm_free(ipsec->ck.s); 
00417     if (ipsec->ik.s) shm_free(ipsec->ik.s); 
00418     shm_free(ipsec);
00419 }

r_tls* new_r_tls ( int  port_tls,
unsigned long  session_hash 
)

Creates a registrar tls container.

This does not insert it in the registrar the strings are duplicated in shm

Parameters:
port_tls - port for UserEndpoint Client
session_hash - TLS Session hash
Returns:
the new r_tls* container or NULL on error

Definition at line 429 of file registrar_storage.c.

References M_NAME, _r_tls::port_tls, and _r_tls::session_hash.

Referenced by P_security_200().

00430 {
00431     r_tls *tls;
00432     
00433     tls = shm_malloc(sizeof(r_tls));
00434     if (!tls) {
00435         LOG(L_ERR,"ERR:"M_NAME":new_r_tls(): Unable to alloc %d bytes\n",
00436             sizeof(r_tls));
00437         return 0;
00438     }
00439     memset(tls,0,sizeof(r_tls));
00440     
00441     tls->port_tls = port_tls;
00442     tls->session_hash = session_hash;       
00443     return tls;
00444 }

void free_r_tls ( r_tls tls  ) 

Frees memory taken by a r_tls structure.

Note:
Must be called with a lock on the domain to avoid races
Parameters:
tls - the r_public to be deallocated

Definition at line 451 of file registrar_storage.c.

Referenced by bin_decode_r_security(), and free_r_security().

00452 {
00453     if (!tls) return;
00454     shm_free(tls);
00455 }

r_security* new_r_security ( str  sec_header,
r_security_type  type,
float  q 
)

Definition at line 457 of file registrar_storage.c.

References M_NAME, _r_security::q, _r_security::sec_header, STR_SHM_DUP, and _r_security::type.

Referenced by save_contact_security().

00458 {
00459     r_security *s=0;
00460 
00461     s = shm_malloc(sizeof(r_security));
00462     if (!s){
00463         LOG(L_ERR,"ERR:"M_NAME":save_contact_security: Error allocating %d bytes.\n",sizeof(r_security));
00464         goto error ;
00465     }
00466     memset(s,0,sizeof(r_security));
00467     
00468     s->type = type;
00469     s->q = q;
00470     STR_SHM_DUP(s->sec_header,sec_header,"save_contact_security");
00471     if (!s->sec_header.s) goto error;   
00472     return s;
00473 error:
00474 out_of_memory:
00475     if (s) shm_free(s);
00476     return 0;
00477 }

void free_r_security ( r_security s  ) 

Definition at line 480 of file registrar_storage.c.

References _r_security::data, free_r_ipsec(), free_r_tls(), _r_security::ipsec, _r_security::sec_header, SEC_IPSEC, SEC_NONE, SEC_TLS, _r_security::tls, and _r_security::type.

Referenced by bin_decode_r_contact(), free_r_contact(), P_security_200(), save_contact_security(), and update_r_contact_sec().

00481 {
00482     if (!s) return;
00483     switch (s->type){
00484         case SEC_NONE:
00485             break;
00486         case SEC_TLS:
00487             if (s->data.tls) free_r_tls(s->data.tls);
00488             break;
00489         case SEC_IPSEC:
00490             if (s->data.ipsec) free_r_ipsec(s->data.ipsec);
00491             break;      
00492     }
00493     if (s->sec_header.s) shm_free(s->sec_header.s);
00494     shm_free(s);
00495 }

r_contact* get_r_contact ( str  host,
int  port,
int  transport 
)

Searches for a r_contact contact and returns it.

Note:
Will lock the hash_slot if found! So release it when you are done!
Parameters:
host - the IP in string format
port - the port number
transport - the transport type
Returns:
- the r_contact found, 0 if not found

Definition at line 505 of file registrar_storage.c.

Referenced by get_r_nat_pinhole(), P_enforce_service_routes(), P_follows_service_routes(), P_NAT_relay(), P_security_200(), P_security_relay(), P_verify_security(), r_assert_identity(), r_is_integrity_protected(), r_is_registered(), S_assign_server(), update_r_contact(), and update_r_contact_sec().

00506 {
00507     r_contact *c=0;
00508     unsigned int hash;
00509     if (!registrar) return 0;
00510     hash = get_contact_hash(host,port,transport,r_hash_size);
00511     r_lock(hash);
00512     c = registrar[hash].head;
00513     while(c){
00514         if (c->port == port &&
00515 //          c->transport == transport && /* because xten doesn't care about protocols */ 
00516             c->host.len == host.len &&
00517             strncasecmp(c->host.s,host.s,host.len)==0) return c;
00518         c = c->next;
00519     }
00520     r_unlock(hash);
00521     return 0;
00522 }

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 
)

Creates a registrar contact This does not insert it in the registrar.

Parameters:
host - the host part of the contact, in string
port - the port number of the contact
transport - the transport of the contact
uri - URI of the contact
reg_state - Registration state
expires - expires in
service_route - array of service routes
service_route_cnt - the size of the array above
Returns:
the new r_contact* or NULL on error

Definition at line 537 of file registrar_storage.c.

Referenced by add_r_contact().

00539 {
00540     r_contact *c;
00541     int i;
00542     
00543     c = shm_malloc(sizeof(r_contact));
00544     if (!c) {
00545         LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
00546             sizeof(r_contact));
00547         goto error;
00548     }
00549     memset(c,0,sizeof(r_contact));
00550     
00551     STR_SHM_DUP(c->host,host,"new_r_contact");
00552     c->port = port;
00553     c->transport = transport;
00554     c->hash = get_contact_hash(host,port,transport,r_hash_size);
00555     STR_SHM_DUP(c->uri,uri,"new_r_contact");        
00556     c->reg_state = reg_state;
00557     c->expires = expires;   
00558         
00559     if (service_route_cnt && service_route){
00560         c->service_route = shm_malloc(service_route_cnt*sizeof(str));
00561         if (!c->service_route){
00562             LOG(L_ERR,"ERR:"M_NAME":new_r_contact(): Unable to alloc %d bytes\n",
00563                 service_route_cnt*sizeof(str));
00564             goto error;
00565         }
00566         for(i=0;i<service_route_cnt;i++)
00567             STR_SHM_DUP(c->service_route[i],service_route[i],"new_r_contact");
00568         c->service_route_cnt = service_route_cnt;
00569     }
00570         
00571     return c;
00572 error:
00573 out_of_memory:
00574     if (c){
00575         free_r_contact(c);          
00576     }
00577     return 0;
00578 }

r_contact* add_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 
)

Creates and Adds a new r_contact.

Note:
Aquires the lock on the hash_slot on success, so release it when you are done.

When calling be sure that get_r_contact(...) returns 0, to avoid unreachable duplicates

Parameters:
host - the host part of the contact, in string
port - the port number of the contact
transport - the transport of the contact
uri - URI of the contact
reg_state - Registration state
expires - expires in
service_route - array of service routes
service_route_cnt - the size of the array above
pinhole - NAT pin hole
Returns:
the newly added r_contact, 0 on error

Definition at line 595 of file registrar_storage.c.

Referenced by update_r_contact(), and update_r_contact_sec().

00597 {
00598     r_contact *c;
00599 
00600     if (!registrar) return 0;
00601     c = new_r_contact(host,port,transport,uri,reg_state, expires, service_route, service_route_cnt);
00602     if (!c) return 0;
00603     c->next=0;
00604     r_lock(c->hash);
00605         c->prev=registrar[c->hash].tail;
00606         if (c->prev) c->prev->next = c;
00607         registrar[c->hash].tail = c;
00608         if (!registrar[c->hash].head) registrar[c->hash].head=c;
00609         c->pinhole = pinhole;
00610     return c;
00611 }

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 
)

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.
Parameters:
host - the host part of the contact, in string
port - the port number of the contact
transport - the transport of the contact
uri - URI of the contact
reg_state - Registration state
expires - expires in
service_route - array of service routes
service_route_cnt - the size of the array above
pinhole - NAT pin hole
Returns:
the updated added r_contact, 0 on error

Definition at line 628 of file registrar_storage.c.

Referenced by