Definition in file registrar.h.
#include "../../sr_module.h"
Go to the source code of this file.
Defines | |
| #define | IMS_USER_NOT_REGISTERED 0 |
| User Not Registered. | |
| #define | IMS_USER_REGISTERED 1 |
| User registered. | |
| #define | IMS_USER_UNREGISTERED -1 |
| User unregistered (not registered but with services for unregistered state). | |
| #define | IMS_USER_DEREGISTERED -2 |
| User de-registered. | |
Functions | |
| void | registrar_timer (unsigned int ticks, void *param) |
| The Registrar timer looks for expires contacts and removes them. | |
| int | S_assign_server (struct sip_msg *msg, char *str1, char *str2) |
| Does the Server Assignment procedures, assigning this S-CSCF to the user. | |
| int | S_assign_server_unreg (struct sip_msg *msg, char *str1, char *str2) |
| Does the Server Assignment procedures, assigning this S-CSCF to the user without previous registration. | |
| int | S_update_contacts (struct sip_msg *msg, char *str1, char *str2) |
| Save the contacts. | |
| int | SAR (struct sip_msg *msg, str realm, str public_identity, str private_identity, int assignment_type, int data_available) |
| Sends a SAR. | |
| int | save_location (struct sip_msg *msg, int assignment_type, str *xml, str *ccf1, str *ccf2, str *ecf1, str *ecf2) |
| Save the contacts. | |
| int | S_lookup (struct sip_msg *msg, char *str1, char *str2) |
| Lookup for the Request-URI in registrar and rewrite request URI with the contact address. | |
| int | r_is_registered_id (str public_identity) |
| Finds if the user is registered at this S-CSCF. | |
| int | r_is_not_registered_id (str public_identity) |
| Finds if the user is not registered at this S-CSCF. | |
| int | r_is_unregistered_id (str public_identity) |
| Finds if the user is unregistered at this S-CSCF. | |
| int | S_is_not_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the user in To header is not registered at this S-CSCF. | |
| int | S_term_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the terminating user (in the RequestURI) is registered at this S-CSCF. | |
| int | S_term_not_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the terminating user (in the RequestURI) is not registered at this S-CSCF. | |
| int | S_term_unregistered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the terminating user (in the RequestURI) is unregistered at this S-CSCF. | |
| int | S_orig_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the originating user (in P-Asserted-Identity) is registered at this S-CSCF. | |
| int | S_orig_not_registered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the originating user (in P-Asserted-Identity) is not registered at this S-CSCF. | |
| int | S_orig_unregistered (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the originating user (in P-Asserted-Identity) is unregistered at this S-CSCF. | |
| int | S_mobile_originating (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the message contains as first route the specific service route for originating case (indicated in the Service-Route at registration), or if the topmost route contains the "orig" parameter. | |
| int | S_originating_barred (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the originating user is barred. | |
| int | S_terminating_barred (struct sip_msg *msg, char *str1, char *str2) |
| Finds if the terminating user is barred. | |
| int | S_add_p_asserted_identity (struct sip_msg *msg, char *str1, char *str2) |
| Adds suplimentary P-Asserted-Identity. | |
| #define IMS_USER_NOT_REGISTERED 0 |
| #define IMS_USER_REGISTERED 1 |
| #define IMS_USER_UNREGISTERED -1 |
User unregistered (not registered but with services for unregistered state).
Definition at line 67 of file registrar.h.
| #define IMS_USER_DEREGISTERED -2 |
| void registrar_timer | ( | unsigned int | ticks, | |
| void * | param | |||
| ) |
The Registrar timer looks for expires contacts and removes them.
| ticks | - the current time | |
| param | - pointer to the domain_list |
Definition at line 91 of file registrar.c.
References _r_public::aor, AVP_IMS_SAR_TIMEOUT_DEREGISTRATION, AVP_IMS_SAR_TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME, cscf_get_realm_from_uri(), del_r_contact(), del_r_public(), del_r_subscriber(), DEREGISTERED, _r_contact::expires, get_r_public_previous_lock(), _r_public::hash, _r_public::head, _r_contact::head, r_hash_slot::head, if, IMS_REGISTRAR_CONTACT_EXPIRED, M_NAME, _r_subscriber::next, _r_public::next, _r_contact::next, NOT_REGISTERED, P_security_drop(), _r_contact::pinhole, ims_subscription::private_identity, ims_service_profile::public_identities, ims_service_profile::public_identities_cnt, ims_public_identity::public_identity, r_act_time(), r_hash_size, r_lock(), r_unlock(), r_valid_contact(), r_valid_subscriber(), REG_PENDING, _r_public::reg_state, _r_contact::reg_state, REGISTERED, registrar, _r_public::s, S_event_reg(), SAR(), SEC_IPSEC, SEC_TLS, _r_contact::security, _r_contact::security_temp, server_assignment_store_data, ims_subscription::service_profiles, ims_subscription::service_profiles_cnt, _r_public::shead, _r_subscriber::subscriber, time_now, _r_security::type, UNREGISTERED, and _r_contact::uri.
00092 { 00093 r_contact *c,*cn; 00094 int i; 00095 #ifdef WITH_IMS_PM 00096 int impu_cnt=0,contact_cnt=0,ipsec_cnt=0,tls_cnt=0,nat_cnt=0; 00097 r_public *rp; 00098 #endif 00099 00100 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Called at %d\n",ticks); 00101 if (!registrar) registrar = (r_hash_slot*)param; 00102 00103 r_act_time(); 00104 00105 for(i=0;i<r_hash_size;i++){ 00106 r_lock(i); 00107 c = registrar[i].head; 00108 while(c){ 00109 cn = c->next; 00110 switch (c->reg_state){ 00111 case NOT_REGISTERED: 00112 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> Not Registered and removed.\n", 00113 c->uri.len,c->uri.s); 00114 del_r_contact(c); 00115 break; 00116 case REGISTERED: 00117 if (c->expires<=time_now) { 00118 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> expired and Deregistered.\n", 00119 c->uri.len,c->uri.s); 00120 if (c->security){ 00121 /* If we have IPSec SAs, we keep them 60 seconds more to relay further messages */ 00122 c->reg_state = DEREGISTERED; 00123 c->expires = time_now + 60; 00124 }else{ 00125 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> expired and removed.\n", 00126 c->uri.len,c->uri.s); 00127 del_r_contact(c); 00128 } 00129 } 00130 #ifdef WITH_IMS_PM 00131 else { 00132 contact_cnt++; 00133 for(rp=c->head;rp;rp=rp->next) 00134 impu_cnt++; 00135 if (c->security && c->security->type==SEC_IPSEC) ipsec_cnt++; 00136 if (c->security && c->security->type==SEC_TLS) tls_cnt++; 00137 if (c->pinhole) nat_cnt++; 00138 } 00139 #endif 00140 break; 00141 case DEREGISTERED: 00142 if (c->expires<=time_now) { 00143 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> expired and removed.\n", 00144 c->uri.len,c->uri.s); 00145 P_security_drop(c,c->security); 00146 P_security_drop(c,c->security_temp); 00147 del_r_contact(c); 00148 } 00149 break; 00150 case REG_PENDING: 00151 if (c->expires<=time_now) { 00152 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> Registration pending expired and removed.\n", 00153 c->uri.len,c->uri.s); 00154 P_security_drop(c,c->security); 00155 P_security_drop(c,c->security_temp); 00156 del_r_contact(c); 00157 } 00158 break; 00159 } 00160 if (pcscf_nat_enable && pcscf_nat_ping) nat_send_ping(c); 00161 c = cn; 00162 } 00163 r_unlock(i); 00164 } 00165 print_r(L_INFO); 00166 #ifdef WITH_IMS_PM 00167 IMS_PM_LOG01(RD_NbrContact,contact_cnt); 00168 IMS_PM_LOG01(RD_NbrIMPU,impu_cnt); 00169 IMS_PM_LOG01(RD_NbrIPSecSA,ipsec_cnt); 00170 IMS_PM_LOG01(RD_NbrTLSSA,tls_cnt); 00171 IMS_PM_LOG01(RD_NbrNATPinHoles,nat_cnt); 00172 #endif 00173 }
| int S_assign_server | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Does the Server Assignment procedures, assigning this S-CSCF to the user.
Covered cases: AVP_IMS_SAR_NO_ASSIGNMENT = 0 AVP_IMS_SAR_REGISTRATION = 1, YES,HERE AVP_IMS_SAR_RE_REGISTRATION = 2, AVP_IMS_SAR_UNREGISTERED_USER = 3, in S_assign_server_unreg AVP_IMS_SAR_TIMEOUT_DEREGISTRATION = 4, AVP_IMS_SAR_USER_DEREGISTRATION = 5, YES,HERE AVP_IMS_SAR_TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME = 6, AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME = 7, YES,HERE AVP_IMS_SAR_ADMINISTRATIVE_DEREGISTRATION = 8, AVP_IMS_SAR_AUTHENTICATION_FAILURE = 9, AVP_IMS_SAR_AUTHENTICATION_TIMEOUT = 10, AVP_IMS_SAR_DEREGISTRATION_TOO_MUCH_DATA
| msg | - the SIP REGISTER message (that is authorized) | |
| str1 | - the realm to look for in Authorization | |
| str2 | - not used |
Definition at line 302 of file registrar.c.
References AVP_IMS_SAR_NO_ASSIGNMENT, AVP_IMS_SAR_RE_REGISTRATION, AVP_IMS_SAR_REGISTRATION, AVP_IMS_SAR_USER_DATA_ALREADY_AVAILABLE, AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE, AVP_IMS_SAR_USER_DEREGISTRATION, AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME, ci, cscf_get_max_expires(), cscf_get_private_identity(), cscf_get_public_identity(), cscf_parse_contacts(), CSCF_RETURN_BREAK, CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, drop_auth_userdata(), get_r_contact(), get_r_public(), _r_public::hash, _r_public::head, M_NAME, _r_contact::next, r_is_registered_id(), r_unlock(), SAR(), save_location(), and server_assignment_store_data.
00303 { 00304 int ret=CSCF_RETURN_FALSE; 00305 str private_identity,public_identity,realm; 00306 int assignment_type = AVP_IMS_SAR_NO_ASSIGNMENT; 00307 int data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE; 00308 int expires; 00309 r_public *p; 00310 int require_user_data=0; 00311 contact_body_t* b=0; 00312 struct hdr_field *h=0; 00313 contact_t *ci=0; 00314 r_contact *c=0; 00315 int n_contacts=0,contacts_reg=0; 00316 00317 LOG(L_DBG,"DBG:"M_NAME":S_assign_server: Assigning server...\n"); 00318 00319 /* First check the parameters */ 00320 if (msg->first_line.type!=SIP_REQUEST) 00321 { 00322 LOG(L_ERR,"ERR:"M_NAME":S_assign_server: This message is not a request\n"); 00323 goto error; 00324 } 00325 00326 realm.s = str1; realm.len = strlen(str1); 00327 if (!realm.len) { 00328 LOG(L_ERR,"ERR:"M_NAME":S_assign_server: No realm found\n"); 00329 return CSCF_RETURN_BREAK; 00330 } 00331 00332 private_identity = cscf_get_private_identity(msg,realm); 00333 00334 public_identity = cscf_get_public_identity(msg); 00335 if (!public_identity.len) { 00336 LOG(L_ERR,"ERR:"M_NAME":S_assign_server: public identity missing\n"); 00337 return ret; 00338 } 00339 00340 expires = cscf_get_max_expires(msg); 00341 00342 if (expires>0) { 00343 if (r_is_registered_id(public_identity)) 00344 assignment_type = AVP_IMS_SAR_RE_REGISTRATION; 00345 else{ 00346 assignment_type = AVP_IMS_SAR_REGISTRATION; 00347 require_user_data=1; 00348 } 00349 } 00350 else { 00351 if (server_assignment_store_data) 00352 assignment_type = AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME; 00353 else assignment_type = AVP_IMS_SAR_USER_DEREGISTRATION; 00354 00355 b = cscf_parse_contacts(msg); 00356 00357 if (!b||(!b->contacts && !b->star)) { 00358 LOG(L_ERR,"ERR:"M_NAME":S_assign_server: No contacts found - this was just bindings fetch, no SAR done\n"); 00359 ret = CSCF_RETURN_TRUE; 00360 goto done; 00361 } 00362 00363 if (!b->star){ 00364 // If not all contacts would be de-registered now, then we actually skip the SAR 00365 p = get_r_public(public_identity); 00366 if(!p) goto error; 00367 00368 for(h=msg->contact;h;h=h->next){ 00369 if (h->type==HDR_CONTACT_T && h->parsed){ 00370 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){ 00371 if (get_r_contact(p,ci->uri)) 00372 n_contacts++; 00373 } 00374 } 00375 } 00376 00377 for(c=p->head;c;c=c->next) 00378 contacts_reg++; 00379 r_unlock(p->hash); 00380 00381 if (n_contacts < contacts_reg){ 00382 // There are still contacts left for this public id 00383 drop_auth_userdata(private_identity,public_identity); 00384 ret = save_location(msg,assignment_type,0,0,0,0,0); 00385 goto done; 00386 } 00387 } 00388 } 00389 00390 //TODO 00391 //if (userdataavailable) data_available = AVP_IMS_SAR_USER_DATA_ALREADY_AVAILABLE; 00392 //else 00393 00394 if(require_user_data) 00395 data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE; 00396 else 00397 data_available = AVP_IMS_SAR_USER_DATA_ALREADY_AVAILABLE; 00398 00399 ret = SAR(msg,realm,public_identity,private_identity,assignment_type,data_available); 00400 00401 done: 00402 return ret; 00403 error: 00404 ret = CSCF_RETURN_ERROR; 00405 return ret; 00406 }
| int S_assign_server_unreg | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Does the Server Assignment procedures, assigning this S-CSCF to the user without previous registration.
Covered cases: AVP_IMS_SAR_NO_ASSIGNMENT = 0 AVP_IMS_SAR_REGISTRATION = 1, YES, NOT HERE AVP_IMS_SAR_RE_REGISTRATION = 2, AVP_IMS_SAR_UNREGISTERED_USER = 3, YES, HERE AVP_IMS_SAR_TIMEOUT_DEREGISTRATION = 4, AVP_IMS_SAR_USER_DEREGISTRATION = 5, YES, NOT HERE AVP_IMS_SAR_TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME = 6, AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME = 7, YES, NOT HERE AVP_IMS_SAR_ADMINISTRATIVE_DEREGISTRATION = 8, AVP_IMS_SAR_AUTHENTICATION_FAILURE = 9, AVP_IMS_SAR_AUTHENTICATION_TIMEOUT = 10, AVP_IMS_SAR_DEREGISTRATION_TOO_MUCH_DATA
| msg | - the SIP REGISTER message (that is authorized) | |
| str1 | - the realm to look for in Authorization | |
| str2 | - direction - "orig" or "term" |
Definition at line 429 of file registrar.c.
References AVP_IMS_SAR_NO_ASSIGNMENT, AVP_IMS_SAR_UNREGISTERED_USER, AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE, cscf_get_asserted_identity(), cscf_get_public_identity_from_requri(), CSCF_RETURN_BREAK, CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, DLG_MOBILE_ORIGINATING, DLG_MOBILE_TERMINATING, get_dialog_direction(), M_NAME, and SAR().
00430 { 00431 int ret=CSCF_RETURN_FALSE; 00432 str private_identity={0,0},public_identity={0,0},realm={0,0}; 00433 int assignment_type = AVP_IMS_SAR_NO_ASSIGNMENT; 00434 int data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE; 00435 00436 /* First check the parameters */ 00437 if (msg->first_line.type!=SIP_REQUEST) 00438 { 00439 LOG(L_ERR,"ERR:"M_NAME":S_assign_server_unreg: This message is not a request\n"); 00440 goto error; 00441 } 00442 00443 realm.s = str1; realm.len = strlen(str1); 00444 if (!realm.len) { 00445 LOG(L_ERR,"ERR:"M_NAME":S_assign_server_unreg: No realm found\n"); 00446 return CSCF_RETURN_BREAK; 00447 } 00448 00449 enum s_dialog_direction dir = get_dialog_direction(str2); 00450 00451 switch (dir){ 00452 case DLG_MOBILE_ORIGINATING: 00453 public_identity = cscf_get_asserted_identity(msg); 00454 if (!public_identity.len) { 00455 LOG(L_DBG,"DBG:"M_NAME":S_assign_server_unreg(orig): public identity missing\n"); 00456 return ret; 00457 } 00458 break; 00459 case DLG_MOBILE_TERMINATING: 00460 public_identity = cscf_get_public_identity_from_requri(msg); 00461 if (!public_identity.len) { 00462 LOG(L_DBG,"DBG:"M_NAME":S_assign_server_unreg(term): public identity missing\n"); 00463 return ret; 00464 } 00465 break; 00466 default: 00467 LOG(L_ERR,"ERR:"M_NAME":S_assign_server_unreg: bad dialog direction parameter\n"); 00468 goto error; 00469 } 00470 00471 assignment_type = AVP_IMS_SAR_UNREGISTERED_USER; 00472 00473 //TODO 00474 //if (userdataavailable) data_available = AVP_IMS_SAR_USER_DATA_ALREADY_AVAILABLE; 00475 //else 00476 data_available = AVP_IMS_SAR_USER_DATA_NOT_AVAILABLE; 00477 00478 ret = SAR(0,realm,public_identity,private_identity,assignment_type,data_available); 00479 00480 return ret; 00481 error: 00482 ret = CSCF_RETURN_ERROR; 00483 return ret; 00484 }
| int S_update_contacts | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Save the contacts.
| msg | - the SIP Register that contains the Expire and Contact headers | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 1166 of file registrar.c.
References save_location().
01167 { 01168 return save_location(msg, -1,0,0,0,0,0); 01169 }
| int SAR | ( | struct sip_msg * | msg, | |
| str | realm, | |||
| str | public_identity, | |||
| str | private_identity, | |||
| int | assignment_type, | |||
| int | data_available | |||
| ) |
Sends a SAR.
Can respond with a SIP reply if msg!=0
| msg | - the SIP message | |
| realm | - the realm | |
| public_identity | - public identity | |
| private_identity | - private identity | |
| assignment_type | - assignment type | |
| data_available | - if the data is already available |
Definition at line 498 of file registrar.c.
References AAA_SUCCESS, AAA_UNABLE_TO_COMPLY, cdp_binds::AAAFreeMessage, AVP_IMS_SAR_ADMINISTRATIVE_DEREGISTRATION, AVP_IMS_SAR_TIMEOUT_DEREGISTRATION, AVP_IMS_SAR_TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME, AVP_IMS_SAR_UNREGISTERED_USER, AVP_IMS_SAR_USER_DEREGISTRATION, AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME, cdpb, cscf_get_realm_from_uri(), CSCF_RETURN_BREAK, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, Cx_get_charging_info(), Cx_get_experimental_result_code(), Cx_get_result_code(), Cx_get_user_data(), Cx_SAR(), drop_auth_userdata(), MSG_403_AUTH_SCHEME_UNSOPPORTED, MSG_403_IDENTITIES_DONT_MATCH, MSG_403_UNABLE_TO_COMPLY, MSG_403_UNKOWN_EXPERIMENTAL_RC, MSG_403_UNKOWN_RC, MSG_403_USER_UNKNOWN, MSG_480_DIAMETER_MISSING_AVP, MSG_480_DIAMETER_TIMEOUT_SAR, RC_IMS_DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED, RC_IMS_DIAMETER_ERROR_IDENTITIES_DONT_MATCH, RC_IMS_DIAMETER_ERROR_USER_UNKNOWN, S_REGISTER_reply(), save_location(), and scscf_name_str.
Referenced by registrar_timer(), S_assign_server(), and S_assign_server_unreg().
00500 { 00501 AAAMessage *saa; 00502 int rc=-1,experimental_rc=-1; 00503 str xml={0,0},ccf1={0,0},ccf2={0,0},ecf1={0,0},ecf2={0,0}; 00504 00505 if (realm.len==0){ 00506 realm = cscf_get_realm_from_uri(private_identity); 00507 } 00508 saa = Cx_SAR(msg,public_identity,private_identity,scscf_name_str,realm, 00509 assignment_type,data_available); 00510 00511 if (!saa){ 00512 //TODO - add the warning code 99 in the reply 00513 if (msg) S_REGISTER_reply(msg,480,MSG_480_DIAMETER_TIMEOUT_SAR); 00514 goto error; 00515 } 00516 00517 if (!Cx_get_result_code(saa,&rc)&& 00518 !Cx_get_experimental_result_code(saa,&experimental_rc)) 00519 { 00520 if (msg) S_REGISTER_reply(msg,480,MSG_480_DIAMETER_MISSING_AVP); 00521 goto done; 00522 } 00523 00524 switch(rc){ 00525 case -1: 00526 switch(experimental_rc){ 00527 case RC_IMS_DIAMETER_ERROR_USER_UNKNOWN: 00528 if (msg) S_REGISTER_reply(msg,403,MSG_403_USER_UNKNOWN); 00529 break; 00530 case RC_IMS_DIAMETER_ERROR_IDENTITIES_DONT_MATCH: 00531 if (msg) S_REGISTER_reply(msg,403,MSG_403_IDENTITIES_DONT_MATCH); 00532 break; 00533 case RC_IMS_DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED: 00534 if (msg) S_REGISTER_reply(msg,403,MSG_403_AUTH_SCHEME_UNSOPPORTED); 00535 break; 00536 00537 default: 00538 if (msg) S_REGISTER_reply(msg,403,MSG_403_UNKOWN_EXPERIMENTAL_RC); 00539 } 00540 break; 00541 00542 case AAA_UNABLE_TO_COMPLY: 00543 if (msg) S_REGISTER_reply(msg,403,MSG_403_UNABLE_TO_COMPLY); 00544 break; 00545 00546 case AAA_SUCCESS: 00547 goto success; 00548 break; 00549 00550 default: 00551 if (msg) S_REGISTER_reply(msg,403,MSG_403_UNKOWN_RC); 00552 } 00553 00554 goto done; 00555 00556 success: 00557 xml = Cx_get_user_data(saa); 00558 00559 if (assignment_type==AVP_IMS_SAR_TIMEOUT_DEREGISTRATION || 00560 assignment_type==AVP_IMS_SAR_USER_DEREGISTRATION || 00561 assignment_type==AVP_IMS_SAR_TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME || 00562 assignment_type==AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME || 00563 assignment_type==AVP_IMS_SAR_ADMINISTRATIVE_DEREGISTRATION 00564 ) 00565 { 00566 drop_auth_userdata(private_identity,public_identity); 00567 } 00568 00569 Cx_get_charging_info(saa,&ccf1,&ccf2,&ecf1,&ecf2); 00570 if (msg||assignment_type==AVP_IMS_SAR_UNREGISTERED_USER){ 00571 int ret = save_location(msg,assignment_type,&xml,&ccf1,&ccf2,&ecf1,&ecf2); 00572 if (saa) cdpb.AAAFreeMessage(&saa); 00573 return ret; 00574 }else{ 00575 /* it was called internally and there is no SIP message to respond to */ 00576 } 00577 if (saa) cdpb.AAAFreeMessage(&saa); 00578 return CSCF_RETURN_TRUE; 00579 done: 00580 if (saa) cdpb.AAAFreeMessage(&saa); 00581 return CSCF_RETURN_FALSE; 00582 error: 00583 if (saa) cdpb.AAAFreeMessage(&saa); 00584 return CSCF_RETURN_BREAK; 00585 }
| int save_location | ( | struct sip_msg * | msg, | |
| int | assignment_type, | |||
| str * | xml, | |||
| str * | ccf1, | |||
| str * | ccf2, | |||
| str * | ecf1, | |||
| str * | ecf2 | |||
| ) |
Save the contacts.
1. Parse the user data 2. Parse contacts in the message 3. Update the contacts accordingly 4. Call function to add to the reply the P-Associated-URI header
| msg | - the SIP Register that contains the Expire and Contact headers | |
| assignment_type | - as sent in the SAR | |
| xml | - the user data as received in the SAA |
Definition at line 1059 of file registrar.c.
References AVP_IMS_SAR_RE_REGISTRATION, AVP_IMS_SAR_REGISTRATION, AVP_IMS_SAR_USER_DEREGISTRATION, AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME, ci, cscf_add_header_rpl(), cscf_get_expires_hdr(), cscf_get_path(), cscf_get_public_identity(), cscf_get_user_agent(), cscf_parse_contacts(), CSCF_RETURN_BREAK, CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, free_user_data(), insert_p_associated_uri(), M_NAME, MSG_423_INTERVAL_TOO_BRIEF, parse_user_data(), print_user_data(), r_is_registered_id(), registration_min_expires, S_REGISTER_reply(), scscf_registration_min_expires, server_assignment_store_data, and update_contacts().
Referenced by S_assign_server(), S_update_contacts(), and SAR().
01060 { 01061 ims_subscription *s=0,*s_copy=0; 01062 contact_t *ci; 01063 contact_body_t* b=0; 01064 unsigned char star=0; 01065 struct hdr_field *h; 01066 str ua={0,0}; 01067 str path={0,0}; 01068 int result = CSCF_RETURN_FALSE; 01069 int max_expires, expires_hdr,expires; 01070 unsigned int exp; 01071 01072 if (xml && xml->len) { 01073 s = parse_user_data(*xml); 01074 s_copy = s; 01075 if (!s){ 01076 LOG(L_ERR,"ERR:"M_NAME":save_location: error parsing user data\n"); 01077 goto error; 01078 } 01079 print_user_data(L_DBG,s); 01080 } 01081 01082 if (msg){ 01083 if (parse_headers(msg, HDR_EOH_F, 0) <0) { 01084 LOG(L_ERR,"ERR:"M_NAME":save_location: error parsing headers\n"); 01085 goto error; 01086 } 01087 01088 b = cscf_parse_contacts(msg); 01089 01090 if (!b||(!b->contacts && !b->star)) { 01091 LOG(L_ERR,"ERR:"M_NAME":save_location: No contacts found\n"); 01092 goto error; 01093 } 01094 01095 /* check for too brief interval for registration */ 01096 expires_hdr = cscf_get_expires_hdr(msg); 01097 max_expires = expires_hdr; 01098 01099 for(h=msg->contact;h;h=h->next) 01100 if (h->type==HDR_CONTACT_T && h->parsed) 01101 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){ 01102 if(ci->expires){ 01103 if (!str2int(&(ci->expires->body), (unsigned int*)&exp)){ 01104 expires = exp; 01105 if (expires>max_expires) max_expires = expires; 01106 } 01107 else expires = -1; 01108 } 01109 else expires = expires_hdr; 01110 if (expires>0 && expires<registration_min_expires){ 01111 if (!cscf_add_header_rpl(msg,&scscf_registration_min_expires)) return CSCF_RETURN_ERROR; 01112 S_REGISTER_reply(msg,423,MSG_423_INTERVAL_TOO_BRIEF); 01113 return CSCF_RETURN_BREAK; 01114 } 01115 } 01116 /* we might get gere and not know what to do actually - e.g. from S_update_contacts */ 01117 if (assignment_type<0){ 01118 if (max_expires>0) { 01119 str public_identity; 01120 public_identity=cscf_get_public_identity(msg); 01121 01122 if (r_is_registered_id(public_identity)) 01123 assignment_type = AVP_IMS_SAR_RE_REGISTRATION; 01124 else 01125 assignment_type = AVP_IMS_SAR_REGISTRATION; 01126 } 01127 else { 01128 if (server_assignment_store_data) 01129 assignment_type = AVP_IMS_SAR_USER_DEREGISTRATION_STORE_SERVER_NAME; 01130 else assignment_type = AVP_IMS_SAR_USER_DEREGISTRATION; 01131 } 01132 } 01133 //LOG(L_CRIT,"max_expires %d assign_type %d\n",max_expires, assignment_type); 01134 01135 ua = cscf_get_user_agent(msg); 01136 01137 path = cscf_get_path(msg); 01138 01139 /* we insert p associated uri first because update will destroy s */ 01140 if (assignment_type==AVP_IMS_SAR_REGISTRATION || 01141 assignment_type==AVP_IMS_SAR_RE_REGISTRATION) 01142 if (!insert_p_associated_uri(msg,s)) goto error; 01143 } 01144 01145 if (b) star = b->star; 01146 else star = 0; 01147 01148 result = update_contacts(msg,assignment_type, star, &s, &ua,&path,ccf1,ccf2,ecf1,ecf2); 01149 01150 if (path.s) pkg_free(path.s); 01151 return result; 01152 error: 01153 if (path.s) pkg_free(path.s); 01154 if (s && s==s_copy) free_user_data(s); 01155 return result; 01156 }
| int S_lookup | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Lookup for the Request-URI in registrar and rewrite request URI with the contact address.
Also adds routing to the destination's path. Depending on the value of append_branches, the request is forked or not on multiple contacts.
| msg | - the SIP message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 1263 of file registrar.c.
References append_branches, cscf_get_terminating_identity(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, get_r_public(), _r_public::hash, _r_public::head, IMS_USER_REGISTERED, M_NAME, r_act_time(), r_add_p_called_party_id(), r_add_route_path(), r_unlock(), r_valid_contact(), _r_public::reg_state, and tmb.
01264 { 01265 int ret=CSCF_RETURN_FALSE,i; 01266 str uri,dst={0,0}; 01267 r_public *p=0; 01268 r_contact *c=0; 01269 01270 LOG(L_DBG,"DBG:"M_NAME":S_lookup: Looking up for contacts\n"); 01271 //print_r(L_INFO); 01272 /* First check the parameters */ 01273 if (msg->first_line.type!=SIP_REQUEST) 01274 { 01275 LOG(L_ERR,"ERR:"M_NAME":S_lookup: This message is not a request\n"); 01276 goto error; 01277 } 01278 01279 if (!cscf_get_terminating_identity(msg,&uri)){ 01280 LOG(L_ERR,"ERR:"M_NAME":S_lookup: Error extracting terminating uri!!!\n"); 01281 return CSCF_RETURN_ERROR; 01282 } 01283 01284 LOG(L_DBG,"DBG:"M_NAME":S_lookup: Looking for <%.*s>\n",uri.len,uri.s); 01285 01286 p = get_r_public(uri); 01287 // pkg_free(uri.s); 01288 if (!p) return CSCF_RETURN_FALSE; 01289 if (p->reg_state!=IMS_USER_REGISTERED){ 01290 r_unlock(p->hash); 01291 return CSCF_RETURN_FALSE; 01292 } 01293 01294 r_act_time(); 01295 c = p->head; 01296 while(c){ 01297 if (r_valid_contact(c)){ 01298 LOG(L_DBG,"DBG:"M_NAME":S_lookup: Found at <%.*s>\n", 01299 c->uri.len,c->uri.s); 01300 01301 r_add_route_path(msg,c); 01302 r_add_p_called_party_id(msg); 01303 01304 if (rewrite_uri(msg, &(c->uri)) < 0) { 01305 LOG(L_ERR,"ERR:"M_NAME":S_lookup: Error rewritting uri with <%.*s>\n", 01306 c->uri.len,c->uri.s); 01307 ret = CSCF_RETURN_ERROR; 01308 } else { 01309 if (c->path.len) { 01310 dst=c->path; 01311 i=0; 01312 while(i<dst.len && dst.s[i]!='<') 01313 i++; 01314 i++; 01315 dst.s += i; 01316 dst.len -= i; 01317 i=0; 01318 while(i<dst.len && (dst.s[i]!='>')) 01319 i++; 01320 dst.len = i; 01321 } 01322 01323 if (*tmb.route_mode==MODE_ONFAILURE) { 01324 LOG(L_DBG,"DEBUG:"M_NAME":S_lookup: MODE_ONFAILURE, appending branch\n"); 01325 /* need to append_branch for this first contact */ 01326 if (append_branch(msg, c->uri.s, c->uri.len, dst.s,dst.len, c->qvalue, 0) == -1) { 01327 LOG(L_ERR,"ERR:"M_NAME":S_lookup: Error appending branch <%.*s>\n", 01328 c->uri.len,c->uri.s); 01329 } 01330 } 01331 01332 msg->dst_uri.s = pkg_malloc(dst.len); 01333 if (!msg->dst_uri.s){ 01334 LOG(L_ERR, "ERR:"M_NAME":S_lookup: Error allocating %d bytes\n", 01335 dst.len); 01336 msg->dst_uri.len=0; 01337 goto error; 01338 } 01339 memcpy(msg->dst_uri.s,dst.s,dst.len); 01340 msg->dst_uri.len = dst.len; 01341 01342 set_ruri_q(c->qvalue); 01343 01344 ret = CSCF_RETURN_TRUE; 01345 if (append_branches){ 01346 c = c->next; 01347 while(c){ 01348 if (r_valid_contact(c)) 01349 if (append_branch(msg, c->uri.s, c->uri.len, dst.s,dst.len, c->qvalue, 0) == -1) { 01350 LOG(L_ERR,"ERR:"M_NAME":S_lookup: Error appending branch <%.*s>\n", 01351 c->uri.len,c->uri.s); 01352 } 01353 c = c->next; 01354 } 01355 } 01356 01357 } 01358 01359 01360 break; 01361 } 01362 c = c->next; 01363 } 01364 01365 if (p) r_unlock(p->hash); 01366 return ret; 01367 error: 01368 if (p) r_unlock(p->hash); 01369 ret=CSCF_RETURN_ERROR; 01370 return ret; 01371 }
| int r_is_registered_id | ( | str | public_identity | ) |
Finds if the user is registered at this S-CSCF.
| public_identity | - the public identity |
Definition at line 1379 of file registrar.c.
References get_r_public(), _r_public::hash, _r_public::head, IMS_USER_REGISTERED, M_NAME, r_act_time(), r_unlock(), r_valid_contact(), and _r_public::reg_state.
Referenced by S_assign_server(), S_orig_registered(), S_term_registered(), and save_location().
01380 { 01381 int ret=0; 01382 r_public *p; 01383 r_contact *c; 01384 01385 LOG(L_DBG,"DBG:"M_NAME":S_is_registered_id: Looking if registered\n"); 01386 // print_r(L_INFO); 01387 /* First check the parameters */ 01388 01389 p = get_r_public(public_identity); 01390 if (!p) return 0; 01391 if (p->reg_state!=IMS_USER_REGISTERED){ 01392 r_unlock(p->hash); 01393 return 0; 01394 } 01395 01396 r_act_time(); 01397 c = p->head; 01398 while(c){ 01399 if (r_valid_contact(c)){ 01400 LOG(L_DBG,"DBG:"M_NAME":S_is_registered_id: Found at <%.*s>\n", 01401 c->uri.len,c->uri.s); 01402 ret = 1; 01403 break; 01404 } 01405 c = c->next; 01406 } 01407 r_unlock(p->hash); 01408 return ret; 01409 }
| int r_is_not_registered_id | ( | str | public_identity | ) |
Finds if the user is not registered at this S-CSCF.
| public_identity | - the SIP message |
Definition at line 1416 of file registrar.c.
References get_r_public(), _r_public::hash, IMS_USER_NOT_REGISTERED, M_NAME, r_unlock(), and _r_public::reg_state.
Referenced by S_is_not_registered(), S_orig_not_registered(), and S_term_not_registered().