registrar.h File Reference


Detailed Description

Serving-CSCF - Registrar-Related Operations.

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

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 Documentation

#define IMS_USER_NOT_REGISTERED   0

User Not Registered.

Definition at line 63 of file registrar.h.

#define IMS_USER_REGISTERED   1

User registered.

Definition at line 65 of file registrar.h.

#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

User de-registered.

Definition at line 69 of file registrar.h.


Function Documentation

void registrar_timer ( unsigned int  ticks,
void *  param 
)

The Registrar timer looks for expires contacts and removes them.

Parameters:
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

Parameters:
msg - the SIP REGISTER message (that is authorized)
str1 - the realm to look for in Authorization
str2 - not used
Returns:
true if ok, false if not, break on error

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

Parameters:
msg - the SIP REGISTER message (that is authorized)
str1 - the realm to look for in Authorization
str2 - direction - "orig" or "term"
Returns:
true if ok, false if not, break on error

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.

Parameters:
msg - the SIP Register that contains the Expire and Contact headers
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if OK, CSCF_RETURN_FALSE if not or CSCF_RETURN_ERROR on error

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

Parameters:
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
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE on error or CSCF_RETURN_BREAK on response sent out

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

Parameters:
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
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE on error or CSCF_RETURN_BREAK on response sent out

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.

Parameters:
msg - the SIP message
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if found, else CSCF_RETURN_FALSE or CSCF_RETURN_ERROR on error

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.

Parameters:
public_identity - the public identity
Returns:
1 if registered, 0 if not or error

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.

Parameters:
public_identity - the SIP message
Returns:
1 if registered, 0 if not or error

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().

01417 {
01418     int ret=0;
01419     r_public *p;
01420 
01421     LOG(L_DBG,"DBG:"M_NAME":S_is_not_registered_id: Looking if NOT registered\n");