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.
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_entry * | I_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_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. | |
| 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_entry * | new_scscf_entry (str name, int score, int orig) |
| scscf_list * | new_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_capabilities * | SCSCF_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_slot * | i_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 h_inc h+=v^(v>>3) |
| int I_get_capabilities | ( | ) |
Refreshes the capabilities list reading them from the db.
Drops the old cache and queries the db
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.
| 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) |
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.
| 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 |
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.
| call_id | - the id of the call |
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 }
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().
1.5.2