scscf_list.c File Reference


Detailed Description

Interrogating-CSCF - Serving-CSCFs Lists.

The I-CSCF performs a serial fork and tries to deliver the requests to the first S-CSCF that responds, from a list.

The list is received from the HSS or created from the received (from HSS) list of mandatory and optional capabilities for that particular user. This is often called capabilities selection.

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

Definition in file scscf_list.c.

#include <values.h>
#include "../../mem/shm_mem.h"
#include "../../dset.h"
#include "../tm/tm_load.h"
#include "scscf_list.h"
#include "db.h"
#include "sip.h"

Go to the source code of this file.

Defines

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

Functions

int I_get_capabilities ()
 Refreshes the capabilities list reading them from the db.
int I_get_capab_match (scscf_capabilities *c, int *m, int mcnt, int *o, int ocnt)
 Returns the matching rank of a S-CSCF.
static scscf_entryI_add_to_scscf_list (scscf_entry *root, str name, int score, int originating)
 Adds the name to the list starting at root, ordered by score.
scscf_entryI_get_capab_ordered (str scscf_name, int *m, int mcnt, int *o, int ocnt, str *p, int pcnt, int orig)
 Returns a list of S-CSCFs that we should try on, based on the capabilities requested.
unsigned int get_call_id_hash (str callid, int hash_size)
 Computes the hash for a string.
int i_hash_table_init (int hash_size)
 Initialize the hash with S-CSCF lists.
void i_hash_table_destroy ()
 Destroy the hash with S-CSCF lists.
void i_lock (unsigned int hash)
 Locks the required part of hash with S-CSCF lists.
void i_unlock (unsigned int hash)
 UnLocks the required part of hash with S-CSCF lists.
scscf_entrynew_scscf_entry (str name, int score, int orig)
scscf_listnew_scscf_list (str call_id, scscf_entry *sl)
int add_scscf_list (str call_id, scscf_entry *sl)
int is_scscf_list (str call_id)
str take_scscf_entry (str call_id)
 Takes on S-CSCF name for the respective Call-ID from the respective name list.
void del_scscf_list (str call_id)
void free_scscf_list (scscf_list *sl)
void print_scscf_list (int log_level)
int I_trans_in_processing (struct sip_msg *msg, char *str1, char *str2)
int I_scscf_select (struct sip_msg *msg, char *str1, char *str2)
int I_scscf_drop (struct sip_msg *msg, char *str1, char *str2)

Variables

tm_binds tmb
 Structure with pointers to tm funcs.
scscf_capabilitiesSCSCF_Capabilities = 0
 list of S-CSCFs and their capabilities
int SCSCF_Capabilities_cnt = 0
 size of list of S-CSCFs and their capabilities
int i_hash_size
 size of the hash table for the S-CSCF lists
i_hash_sloti_hash_table = 0
 the hash table for the S-CSCF lists
static str route_hdr_s = {"Route: <",8}
static str route_hdr_e = {">\r\n",3}


Define Documentation

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

Referenced by get_aor_hash(), get_call_id_hash(), get_contact_hash(), get_hash_auth(), get_p_dialog_hash(), get_s_dialog_hash(), and get_subscription_hash().


Function Documentation

int I_get_capabilities (  ) 

Refreshes the capabilities list reading them from the db.

Drops the old cache and queries the db

Todo:
  • IMPLEMENT A WAY TO PUSH AN EXTERNAL EVENT FOR THIS
Todo:
  • SOLVE THE LOCKING PROBLEM - THIS IS A WRITER
Returns:
1 on success, 0 on failure

Definition at line 90 of file scscf_list.c.

References _scscf_capabilities::cnt, icscf_db_get_capabilities(), icscf_db_get_scscf(), id_s_cscf, M_NAME, SCSCF_Capabilities, SCSCF_Capabilities_cnt, scscf_name, and _scscf_capabilities::scscf_name.

Referenced by icscf_mod_init().

00091 {
00092     int i,j,r;
00093     /* free the old cache */
00094     if (SCSCF_Capabilities!=0){
00095         for(i=0;i<SCSCF_Capabilities_cnt;i++){
00096             if (SCSCF_Capabilities[i].capabilities)
00097                 shm_free(SCSCF_Capabilities[i].capabilities);
00098         }
00099         shm_free(SCSCF_Capabilities);
00100     }
00101     
00102     SCSCF_Capabilities_cnt = icscf_db_get_scscf(&SCSCF_Capabilities);
00103     
00104     r = icscf_db_get_capabilities(&SCSCF_Capabilities,SCSCF_Capabilities_cnt);
00105 
00106     LOG(L_DBG,"DBG:"M_NAME":------  S-CSCF Map with Capabilities  begin ------\n");
00107     if (SCSCF_Capabilities!=0){
00108         for(i=0;i<SCSCF_Capabilities_cnt;i++){
00109             LOG(L_DBG,"DBG:"M_NAME":S-CSCF [%d] <%.*s>\n",
00110                 SCSCF_Capabilities[i].id_s_cscf,
00111                 SCSCF_Capabilities[i].scscf_name.len,
00112                 SCSCF_Capabilities[i].scscf_name.s);
00113             for(j=0;j<SCSCF_Capabilities[i].cnt;j++)
00114             LOG(L_DBG,"DBG:"M_NAME":       \t [%d]\n",
00115              SCSCF_Capabilities[i].capabilities[j]);
00116         }
00117     }
00118     LOG(L_DBG,"DBG:"M_NAME":------  S-CSCF Map with Capabilities  end ------\n");
00119     
00120     return r;
00121 }

int I_get_capab_match ( scscf_capabilities c,
int *  m,
int  mcnt,
int *  o,
int  ocnt 
)

Returns the matching rank of a S-CSCF.

Todo:
  • optimize the search as O(n^2) is hardly desireable
Parameters:
c - the capabilities of the S-CSCF
m - mandatory capabilities list requested
mcnt - mandatory capabilities list size
o - optional capabilities list
ocnt - optional capabilities list sizeint I_get_capab_match(icscf_capabilities *c,int *m,int mcnt,int *o,int ocnt)
Returns:
- -1 if mandatory not satisfied, else count of matched optional capab

Definition at line 133 of file scscf_list.c.

References _scscf_capabilities::capabilities, and _scscf_capabilities::cnt.

Referenced by I_get_capab_ordered().

00134 {
00135     int r=0,i,j,t=0;
00136     for(i=0;i<mcnt;i++){
00137         t=0;
00138         for(j=0;j<c->cnt;j++)
00139             if (m[i]==c->capabilities[j]) {
00140                 t=1;
00141                 break;
00142             }
00143         if (!t) return -1;
00144     }
00145     for(i=0;i<ocnt;i++){
00146         for(j=0;j<c->cnt;j++)
00147             if (o[i]==c->capabilities[j]) r++;
00148     }   
00149     return r;
00150 }

static scscf_entry* I_add_to_scscf_list ( scscf_entry root,
str  name,
int  score,
int  originating 
) [inline, static]

Adds the name to the list starting at root, ordered by score.

Returns the new root

Definition at line 156 of file scscf_list.c.

References new_scscf_entry(), _scscf_entry::next, _scscf_entry::score, and _scscf_entry::scscf_name.

Referenced by I_get_capab_ordered().

00157 {
00158     scscf_entry *x,*i;
00159 
00160     //duplicate?
00161     for(i=root;i;i=i->next)
00162         if (name.len == i->scscf_name.len &&
00163             strncasecmp(name.s,i->scscf_name.s,name.len)==0)
00164                 return root;
00165 
00166     x = new_scscf_entry(name,score, originating);
00167     if (!x) return root;
00168     
00169     if (!root){
00170         return x;
00171     }
00172     if (root->score < x->score){
00173         x->next = root;
00174         return x;
00175     }
00176     i = root;
00177     while(i->next && i->next->score > x->score)
00178         i = i->next;
00179     x->next = i->next;
00180     i->next = x;
00181     return root;
00182 }

scscf_entry* I_get_capab_ordered ( str  scscf_name,
int *  m,
int  mcnt,
int *  o,
int  ocnt,
str *  p,
int  pcnt,
int  orig 
)

Returns a list of S-CSCFs that we should try on, based on the capabilities requested.

Todo:
  • order the list according to matched optionals - r
Parameters:
scscf_name - the first S-CSCF if specified
m - mandatory capabilities list
mcnt - mandatory capabilities list size
o - optional capabilities list
ocnt - optional capabilities list size
orig - indicates originating session case
Returns:
list of S-CSCFs, terminated with a str={0,0}

Definition at line 196 of file scscf_list.c.

References I_add_to_scscf_list(), I_get_capab_match(), M_NAME, SCSCF_Capabilities, SCSCF_Capabilities_cnt, and _scscf_capabilities::scscf_name.

Referenced by I_LIA(), and I_UAA().

00197 {
00198     scscf_entry *list=0;
00199     int i,r;
00200     
00201     if (scscf_name.len) list = I_add_to_scscf_list(list,scscf_name,MAXINT, orig);
00202 
00203     for(i=0;i<pcnt;i++)
00204         list = I_add_to_scscf_list(list,p[i],MAXINT-i,orig);
00205         
00206     for(i=0;i<SCSCF_Capabilities_cnt;i++){
00207         r = I_get_capab_match(SCSCF_Capabilities+i,m,mcnt,o,ocnt);
00208         if (r!=-1){
00209              list = I_add_to_scscf_list(list,SCSCF_Capabilities[i].scscf_name,r, orig);
00210              LOG(L_DBG,"DBG:"M_NAME":I_get_capab_ordered: <%.*s> Added to the list, orig=%d\n",
00211                 SCSCF_Capabilities[i].scscf_name.len,SCSCF_Capabilities[i].scscf_name.s, orig);
00212         }
00213     }
00214     return list;
00215 }

unsigned int get_call_id_hash ( str  callid,
int  hash_size 
) [inline]

Computes the hash for a string.

Definition at line 221 of file scscf_list.c.

References h_inc.

Referenced by add_scscf_list(), del_scscf_list(), is_scscf_list(), and take_scscf_entry().

00222 {
00223 #define h_inc h+=v^(v>>3)
00224    char* p;
00225    register unsigned v;
00226    register unsigned h;
00227 
00228    h=0;
00229    for (p=callid.s; p<=(callid.s+callid.len-4); p+=4){
00230        v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
00231        h_inc;
00232    }
00233    v=0;
00234    for (;p<(callid.s+callid.len); p++) {
00235        v<<=8;
00236        v+=*p;
00237    }
00238    h_inc;
00239 
00240    h=((h)+(h>>11))+((h>>13)+(h>>23));
00241    return (h)%hash_size;
00242 #undef h_inc 
00243 }

int i_hash_table_init ( int  hash_size  ) 

Initialize the hash with S-CSCF lists.

Definition at line 248 of file scscf_list.c.

References i_hash_size, i_hash_table, i_hash_slot::lock, and M_NAME.

Referenced by icscf_mod_init().

00249 {
00250     int i;
00251     
00252     i_hash_size = hash_size;
00253     i_hash_table = shm_malloc(sizeof(i_hash_slot)*i_hash_size);
00254 
00255     if (!i_hash_table) return 0;
00256     
00257     memset(i_hash_table,0,sizeof(i_hash_slot)*i_hash_size);
00258     
00259     for(i=0;i<i_hash_size;i++){
00260         i_hash_table[i].lock = lock_alloc();
00261         if (!i_hash_table[i].lock){
00262             LOG(L_ERR,"ERR:"M_NAME":i_hash_table_init(): Error creating lock\n");
00263             return 0;
00264         }
00265         i_hash_table[i].lock = lock_init(i_hash_table[i].lock);
00266     }
00267             
00268     return 1;
00269 }

void i_hash_table_destroy (  ) 

Destroy the hash with S-CSCF lists.

Definition at line 274 of file scscf_list.c.

References free_scscf_list(), i_hash_slot::head, i_hash_size, i_hash_table, i_lock(), i_unlock(), and _scscf_list::next.

Referenced by icscf_mod_destroy().

00275 {
00276     int i;
00277     scscf_list *sl,*nsl;
00278     for(i=0;i<i_hash_size;i++){
00279         i_lock(i);
00280             sl = i_hash_table[i].head;
00281             while(sl){
00282                 nsl = sl->next;
00283                 free_scscf_list(sl);
00284                 sl = nsl;
00285             }
00286         i_unlock(i);
00287         lock_dealloc(i_hash_table[i].lock);
00288     }
00289     shm_free(i_hash_table);
00290 }

void i_lock ( unsigned int  hash  )  [inline]

Locks the required part of hash with S-CSCF lists.

Definition at line 295 of file scscf_list.c.

References i_hash_table.

Referenced by add_scscf_list(), del_scscf_list(), i_hash_table_destroy(), is_scscf_list(), print_scscf_list(), and take_scscf_entry().

00296 {
00297 //  LOG(L_CRIT,"GET %d\n",hash);
00298     lock_get(i_hash_table[(hash)].lock);
00299 //  LOG(L_CRIT,"GOT %d\n",hash);    
00300 }

void i_unlock ( unsigned int  hash  )  [inline]

UnLocks the required part of hash with S-CSCF lists.

Definition at line 305 of file scscf_list.c.

References i_hash_table.

Referenced by add_scscf_list(), del_scscf_list(), i_hash_table_destroy(), is_scscf_list(), print_scscf_list(), and take_scscf_entry().

00306 {
00307     lock_release(i_hash_table[(hash)].lock);
00308 //  LOG(L_CRIT,"RELEASED %d\n",hash);   
00309 }

scscf_entry* new_scscf_entry ( str  name,
int  score,
int  orig 
)

Definition at line 311 of file scscf_list.c.

References M_NAME, _scscf_entry::next, _scscf_entry::score, and _scscf_entry::scscf_name.

Referenced by I_add_to_scscf_list(), and I_LIA().

00312 {
00313     scscf_entry *x=0;
00314     x = shm_malloc(sizeof(scscf_entry));
00315     if (!x) {   
00316         LOG(L_ERR,"ERR:"M_NAME":new_scscf_entry: Error allocating %d bytes\n",
00317             sizeof(scscf_entry));
00318         return 0;
00319     }
00320     /* duplicate always the scscf_name because of possible list reloads and scscf_name coming in LIA/UAA */
00321     if (orig) x->scscf_name.s = shm_malloc(name.len+5);
00322     else x->scscf_name.s = shm_malloc(name.len);
00323     if (!x->scscf_name.s){  
00324         LOG(L_ERR,"ERR:"M_NAME":new_scscf_entry: Error allocating %d bytes\n",
00325             orig?name.len+5:name.len);
00326         shm_free(x);
00327         return 0;
00328     }
00329     memcpy(x->scscf_name.s,name.s,name.len);
00330     x->scscf_name.len = name.len;
00331     if (orig) {
00332         memcpy(x->scscf_name.s+name.len, ";orig", 5);
00333         x->scscf_name.len += 5;
00334     }
00335     
00336     LOG(L_INFO,"INFO:"M_NAME":new_scscf_entry:  <%.*s>\n",x->scscf_name.len,x->scscf_name.s);
00337     
00338     x->score = score;
00339     x->next = 0;
00340     return x;
00341 }

scscf_list* new_scscf_list ( str  call_id,
scscf_entry sl 
)

Definition at line 344 of file scscf_list.c.

References _scscf_list::call_id, _scscf_list::list, M_NAME, and STR_SHM_DUP.

Referenced by add_scscf_list().

00345 {
00346     scscf_list *l;
00347     
00348     l = shm_malloc(sizeof(scscf_list));
00349     if (!l) {
00350         LOG(L_ERR,"ERR:"M_NAME":new_scscf_list(): Unable to alloc %d bytes\n",
00351             sizeof(scscf_list));
00352         goto error;
00353     }
00354     memset(l,0,sizeof(scscf_list));
00355     
00356     STR_SHM_DUP(l->call_id,call_id,"shm");
00357     l->list = sl;
00358                 
00359     return l;
00360 error:
00361 out_of_memory:
00362     if (l){
00363         shm_free(l);        
00364     }
00365     return 0;
00366 }

int add_scscf_list ( str  call_id,
scscf_entry sl 
)

Definition at line 368 of file scscf_list.c.

References get_call_id_hash(), i_hash_slot::head, i_hash_size, i_hash_table, i_lock(), i_unlock(), new_scscf_list(), _scscf_list::next, _scscf_list::prev, and i_hash_slot::tail.

Referenced by I_LIA(), and I_UAA().

00369 {
00370     scscf_list *l;
00371     unsigned int hash = get_call_id_hash(call_id,i_hash_size);
00372     
00373     l = new_scscf_list(call_id,sl);
00374     if (!l) return 0;       
00375     
00376     i_lock(hash);
00377     l->prev = 0;
00378     l->next = i_hash_table[hash].head;
00379     if (l->next) l->next->prev = l;
00380     i_hash_table[hash].head = l;
00381     if (!i_hash_table[hash].tail) i_hash_table[hash].tail = l;
00382     i_unlock(hash); 
00383     
00384     return 1;
00385 }

int is_scscf_list ( str  call_id  ) 

Definition at line 387 of file scscf_list.c.

References _scscf_list::call_id, get_call_id_hash(), i_hash_slot::head, i_hash_size, i_hash_table, i_lock(), i_unlock(), and _scscf_list::next.

00388 {
00389     scscf_list *l=0;
00390     unsigned int hash = get_call_id_hash(call_id,i_hash_size);
00391 
00392     i_lock(hash);
00393     l = i_hash_table[hash].head;
00394     while(l){
00395         if (l->call_id.len == call_id.len &&
00396             strncasecmp(l->call_id.s,call_id.s,call_id.len)==0) {
00397                 i_unlock(hash);
00398                 return 1;
00399             }
00400         l = l->next;
00401     }
00402     i_unlock(hash);
00403     return 0;
00404 }

str take_scscf_entry ( str  call_id  ) 

Takes on S-CSCF name for the respective Call-ID from the respective name list.

Should shm_free the result.s when no longer needed.

Parameters:
call_id - the id of the call
Returns:
the shm_malloced S-CSCF name if found or empty string if list is empty or does not exists

Definition at line 412 of file scscf_list.c.

References _scscf_list::call_id, get_call_id_hash(), i_hash_slot::head, i_hash_size, i_hash_table, i_lock(), i_unlock(), _scscf_list::list, _scscf_entry::next, _scscf_list::next, and _scscf_entry::scscf_name.

Referenced by I_scscf_select().

00413 {
00414     str scscf={0,0};
00415     scscf_list *l=0;
00416     scscf_entry *sl;
00417     unsigned int hash = get_call_id_hash(call_id,i_hash_size);
00418 
00419     i_lock(hash);
00420     l = i_hash_table[hash].head;
00421     while(l){
00422         if (l->call_id.len == call_id.len &&
00423             strncasecmp(l->call_id.s,call_id.s,call_id.len)==0) {
00424                 if (l->list){
00425                     scscf = l->list->scscf_name;
00426                     sl = l->list->next;
00427                     shm_free(l->list);
00428                     l->list = sl;
00429                 }
00430                 break;
00431             }
00432         l = l->next;
00433     }
00434     i_unlock(hash);
00435     return scscf;
00436 }

void del_scscf_list ( str  call_id  ) 

Definition at line 438 of file scscf_list.c.

References _scscf_list::call_id, free_scscf_list(), get_call_id_hash(), i_hash_slot::head, i_hash_size, i_hash_table, i_lock(), i_unlock(), _scscf_list::next, _scscf_list::prev, and i_hash_slot::tail.

Referenced by I_scscf_drop().

00439 {
00440     scscf_list *l=0;
00441     unsigned int hash = get_call_id_hash(call_id,i_hash_size);
00442 
00443     i_lock(hash);
00444     l = i_hash_table[hash].head;
00445     while(l){
00446         if (l->call_id.len == call_id.len &&
00447             strncasecmp(l->call_id.s,call_id.s,call_id.len)==0) {
00448                 if (l->prev) l->prev->next = l->next;
00449                 else i_hash_table[hash].head = l->next;
00450                 if (l->next) l->next->prev = l->prev;
00451                 else i_hash_table[hash].tail = l->prev;                 
00452                 i_unlock(hash);
00453                 free_scscf_list(l);
00454                 return;
00455             }
00456         l = l->next;
00457     }
00458     i_unlock(hash);
00459 }

void free_scscf_list ( scscf_list sl  ) 

Definition at line 461 of file scscf_list.c.

References _scscf_list::call_id, _scscf_list::list, _scscf_entry::next, and _scscf_entry::scscf_name.

Referenced by del_scscf_list(), and i_hash_table_destroy().

00462 {
00463     scscf_entry *i;
00464     if (!sl) return;
00465     if (sl->call_id.s) shm_free(sl->call_id.s);
00466     while (sl->list) {
00467         i = sl->list->next;
00468         if (sl->list->scscf_name.s) shm_free(sl->list->scscf_name.s);
00469         shm_free(sl->list);
00470         sl->list = i;
00471     }
00472     shm_free(sl);
00473 }

void print_scscf_list ( int  log_level  ) 

Definition at line 475 of file scscf_list.c.

References _scscf_list::call_id, i_hash_slot::head, i_hash_size, i_hash_table, i_lock(), i_unlock(), _scscf_list::list, M_NAME, _scscf_entry::next, and _scscf_list::next.

00476 {
00477     scscf_list *l;
00478     int i;
00479     scscf_entry *sl;
00480     LOG(log_level,"INF:"M_NAME":----------  S-CSCF Lists begin --------------\n");
00481     for(i=0;i<i_hash_size;i++){
00482         i_lock(i);
00483             l = i_hash_table[i].head;
00484             while(l){
00485                 LOG(log_level,"INF:"M_NAME":[%4d] Call-ID: <%.*s> \n",i,
00486                     l->call_id.len,l->call_id.s);
00487                 sl = l->list;
00488                 while(sl){
00489                     LOG(log_level,"INF:"M_NAME":         Score:[%4d] S-CSCF: <%.*s> \n",
00490                         sl->score,
00491                         sl->scscf_name.len,sl->scscf_name.s);                   
00492                     sl = sl->next;
00493                 }
00494                 l = l->next;
00495             }       
00496         i_unlock(i);
00497     }
00498     LOG(log_level,"INF:"M_NAME":----------  S-CSCF Lists end   --------------\n");
00499     
00500 }

int I_trans_in_processing ( struct sip_msg *  msg,
char *  str1,
char *  str2 
)

Definition at line 502 of file scscf_list.c.

References CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, and tmb.

00503 {
00504         unsigned int hash, label;
00505         if (tmb.t_get_trans_ident(msg,&hash,&label)<0)
00506             return CSCF_RETURN_FALSE;
00507         return CSCF_RETURN_TRUE;
00508 }

int I_scscf_select ( struct sip_msg *  msg,
char *  str1,
char *  str2 
)

Definition at line 513 of file scscf_list.c.

References cscf_add_header_first(), cscf_get_call_id(), cscf_reply_transactional(), CSCF_RETURN_BREAK, CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, I_scscf_drop(), M_NAME, MSG_600_FORWARDING_FAILED, scscf_name, STR_APPEND, STR_PKG_DUP, and take_scscf_entry().

00514 {
00515     str call_id,scscf_name={0,0};
00516     struct sip_msg *req;
00517     int result;
00518     str hdr={0,0};
00519 
00520     //print_scscf_list(L_ERR);
00521         
00522     call_id = cscf_get_call_id(msg,0);
00523     LOG(L_DBG,"DBG:"M_NAME":I_scscf_select(): <%.*s>\n",call_id.len,call_id.s);
00524     if (!call_id.len)
00525         return CSCF_RETURN_FALSE;
00526     
00527     scscf_name = take_scscf_entry(call_id);
00528     if (!scscf_name.len){
00529         I_scscf_drop(msg,str1,str2);
00530         cscf_reply_transactional(msg,600,MSG_600_FORWARDING_FAILED);            
00531         return CSCF_RETURN_BREAK;
00532     }
00533     
00534     if (msg->first_line.u.request.method.len==8 &&
00535         strncasecmp(msg->first_line.u.request.method.s,"REGISTER",8)==0) {
00536         /* REGISTER fwding */           
00537         if (str1&&str1[0]=='0'){
00538             /* first time */    
00539             //LOG(L_CRIT,"rewrite uri\n");
00540             if (rewrite_uri(msg, &(scscf_name)) < 0) {
00541                 LOG(L_ERR,"ERR:"M_NAME":I_UAR_forward: Unable to Rewrite URI\n");
00542                 result = CSCF_RETURN_FALSE;
00543             }else
00544                 result = CSCF_RETURN_TRUE;
00545         }else{
00546             /* subsequent */
00547             //LOG(L_CRIT,"append branch\n");
00548             req = msg;//cscf_get_request_from_reply(msg);
00549             append_branch(req,scscf_name.s,scscf_name.len,0,0,0,0);
00550             result = CSCF_RETURN_TRUE;
00551         }
00552     }else{
00553         /* Another request */
00554         result = CSCF_RETURN_TRUE;
00555         
00556         hdr.len = route_hdr_s.len+scscf_name.len+route_hdr_e.len;
00557         hdr.s = pkg_malloc(hdr.len);
00558         if (!hdr.s){
00559             LOG(L_ERR,"ERR:"M_NAME":Mw_REQUEST_forward: Error allocating %d bytes\n",
00560                 hdr.len);
00561             result = CSCF_RETURN_TRUE;
00562         }
00563         hdr.len=0;
00564         STR_APPEND(hdr,route_hdr_s);
00565         STR_APPEND(hdr,scscf_name);
00566         STR_APPEND(hdr,route_hdr_e);
00567     
00568         if (!cscf_add_header_first(msg,&hdr,HDR_ROUTE_T)){
00569             pkg_free(hdr.s);
00570             result = CSCF_RETURN_TRUE;
00571         }
00572         
00573         if (msg->dst_uri.s) pkg_free(msg->dst_uri.s);   
00574         STR_PKG_DUP(msg->dst_uri,scscf_name,"pkg");
00575     }
00576 
00577     if (scscf_name.s) shm_free(scscf_name.s);
00578     return result;
00579 out_of_memory:  
00580     if (scscf_name.s) shm_free(scscf_name.s);
00581     return CSCF_RETURN_ERROR;
00582 }

int I_scscf_drop ( struct sip_msg *  msg,
char *  str1,
char *  str2 
)

Definition at line 584 of file scscf_list.c.

References cscf_get_call_id(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, del_scscf_list(), and M_NAME.

Referenced by I_scscf_select().

00585 {
00586     str call_id;
00587     //print_scscf_list(L_ERR);
00588     call_id = cscf_get_call_id(msg,0);
00589     LOG(L_DBG,"DBG:"M_NAME":I_scscf_drop(): <%.*s>\n",call_id.len,call_id.s);
00590     if (!call_id.len)
00591         return CSCF_RETURN_FALSE;
00592     
00593     del_scscf_list(call_id);
00594     return CSCF_RETURN_TRUE;
00595 }


Variable Documentation

struct tm_binds tmb

Structure with pointers to tm funcs.

Definition at line 257 of file mod.c.

scscf_capabilities* SCSCF_Capabilities = 0

list of S-CSCFs and their capabilities

Definition at line 76 of file scscf_list.c.

Referenced by I_get_capab_ordered(), and I_get_capabilities().

int SCSCF_Capabilities_cnt = 0

size of list of S-CSCFs and their capabilities

Definition at line 77 of file scscf_list.c.

Referenced by I_get_capab_ordered(), and I_get_capabilities().

int i_hash_size

size of the hash table for the S-CSCF lists

Definition at line 79 of file scscf_list.c.

Referenced by add_scscf_list(), del_scscf_list(), i_hash_table_destroy(), i_hash_table_init(), is_scscf_list(), print_scscf_list(), and take_scscf_entry().

i_hash_slot* i_hash_table = 0

the hash table for the S-CSCF lists

Definition at line 80 of file scscf_list.c.

Referenced by add_scscf_list(), del_scscf_list(), i_hash_table_destroy(), i_hash_table_init(), i_lock(), i_unlock(), is_scscf_list(), print_scscf_list(), and take_scscf_entry().

str route_hdr_s = {"Route: <",8} [static]

Definition at line 510 of file scscf_list.c.

Referenced by cscf_remove_first_route(), and cscf_remove_own_route().

str route_hdr_e = {">\r\n",3} [static]

Definition at line 511 of file scscf_list.c.

Referenced by cscf_remove_first_route(), and cscf_remove_own_route().


Generated on Sun Oct 12 04:10:25 2008 for Open IMS Core CSCFs by  doxygen 1.5.2