Definition in file registrar.c.
#include <time.h>
#include "../../parser/contact/contact.h"
#include "../../parser/contact/parse_contact.h"
#include "../../ut.h"
#include "../tm/tm_load.h"
#include "../cdp/cdp_load.h"
#include "../../dset.h"
#include "registrar.h"
#include "registration.h"
#include "mod.h"
#include "registrar_parser.h"
#include "registrar_storage.h"
#include "sip.h"
#include "cx.h"
#include "cx_avp.h"
#include "sip_messages.h"
#include "dlg_state.h"
Go to the source code of this file.
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 | SAR (struct sip_msg *msg, str realm, str public_identity, str private_identity, int assignment_type, int data_available) |
| Sends a SAR. | |
| static int | r_calc_expires (contact_t *c, unsigned int expires_hdr) |
| Calculates the expiration time for one contact. | |
| int | r_calc_contact_q (param_t *_q, qvalue_t *_r) |
| static int | r_add_contact (struct sip_msg *msg, str uri, int expires, qvalue_t qvalue) |
| Adds a Contact header to the reply, containing the approved expires. | |
| static int | update_contacts (struct sip_msg *msg, int assignment_type, unsigned char is_star, ims_subscription **s, str *ua, str *path, str *ccf1, str *ccf2, str *ecf1, str *ecf2) |
| Updates the contacts in the registrar with the new values received, for the addresses received in the SAA. | |
| int | insert_p_associated_uri (struct sip_msg *msg, ims_subscription *s) |
| Adds to the response the P-Associated-URI header. | |
| 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_update_contacts (struct sip_msg *msg, char *str1, char *str2) |
| Save the contacts. | |
| static int | r_add_route_path (struct sip_msg *msg, r_contact *c) |
| Adds a Route header containing the saved Path. | |
| static int | r_add_p_called_party_id (struct sip_msg *msg) |
| Adds the P-Called-Party-ID header containing the Request-URI before that will be resolved to the contact address. | |
| 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_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_add_p_asserted_identity (struct sip_msg *msg, char *str1, char *str2) |
| Adds suplimentary P-Asserted-Identity. | |
| 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_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_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_is_barred (str public_identity) |
| Finds if the user exists and it is barred. | |
| 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. | |
Variables | |
| tm_binds | tmb |
| Structure with pointers to tm funcs. | |
| cdp_binds | cdpb |
| Structure with pointers to cdp funcs. | |
| int | r_hash_size |
| Size of S-CSCF registrar hash table. | |
| r_hash_slot * | registrar |
| The S-CSCF registrar. | |
| str | scscf_name_str |
| fixed name of the S-CSCF | |
| str | scscf_service_route_uri |
| just the service route uri | |
| str | scscf_registration_min_expires |
| fixed minimum registration expiration time | |
| int | server_assignment_store_data |
| whether to ask to keep the data in SAR | |
| int | registration_default_expires |
| the default value for expires if none found | |
| int | registration_min_expires |
| minimum registration expiration time | |
| int | registration_max_expires |
| maximum registration expiration time | |
| int | registration_disable_early_ims |
| if to disable the Early-IMS checks | |
| time_t | time_now |
| Current time of the S-CSCF registrar. | |
| int | append_branches |
| if to append branches | |
| str | hdr_p_associated_uri1 = {"P-Associated-URI: <",19} |
| str | hdr_p_associated_uri2 = {">, <",4} |
| str | hdr_p_associated_uri3 = {">\r\n",3} |
| str | route_hdr1 = {"Route: ",7} |
| str | route_hdr2 = {"\r\n",2} |
| str | p_called_party_id_hdr1 = {"P-Called-Party-ID: <",20} |
| str | p_called_party_id_hdr2 = {">\r\n",3} |
| static str | p_asserted_identity_s = {"P-Asserted-Identity: <",22} |
| static str | p_asserted_identity_e = {">\r\n",3} |
| static str | p_asserted_identity_param = {";user=phone",11} |
| static str | p_asserted_identity_tel = {"tel:",4} |
| static str | route_header = {"Route",5} |
| 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 109 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_contact::head, _r_public::head, r_hash_slot::head, if, IMS_REGISTRAR_CONTACT_EXPIRED, M_NAME, _r_subscriber::next, _r_contact::next, _r_public::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_contact::reg_state, _r_public::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.
00110 { 00111 r_public *p,*pn,*rpublic; 00112 r_contact *c,*c2=0,*cn,*cn2=0; 00113 r_subscriber *s,*sn,*s2=0,*sn2=0; 00114 int i,j,n,assignment_type,sar_res; 00115 ims_public_identity *pi=0; 00116 r_hash_slot *r; 00117 int rpublic_hash; 00118 00119 #ifdef WITH_IMS_PM 00120 int impu_cnt=0,contact_cnt=0,subs_cnt=0; 00121 #endif 00122 00123 00124 r = param; 00125 00126 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Called at %d\n",ticks); 00127 00128 r_act_time(); 00129 00130 for(i=0;i<r_hash_size;i++){ 00131 r_lock(i); 00132 p = r[i].head; 00133 while(p){ 00134 pn = p->next; 00135 c = p->head; 00136 00137 while(c){ 00138 cn = c->next; 00139 if (!r_valid_contact(c)){ 00140 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> expired and removed.\n", 00141 c->uri.len,c->uri.s); 00142 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_EXPIRED,1);/* send now because we might drop the dialog soon */ 00143 del_r_contact(p,c); 00144 } 00145 #ifdef WITH_IMS_PM 00146 else contact_cnt++; 00147 #endif 00148 c = cn; 00149 } 00150 s = p->shead; 00151 while(s){ 00152 sn = s->next; 00153 if (!r_valid_subscriber(s)){ 00154 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Subscriber <%.*s> expired and removed.\n", 00155 s->subscriber.len,s->subscriber.s); 00156 del_r_subscriber(p,s); 00157 } 00158 #ifdef WITH_IMS_PM 00159 else subs_cnt++; 00160 #endif 00161 s = sn; 00162 } 00163 00164 if (!p->head){/* no more contacts, then deregister it */ 00165 switch (p->reg_state){ 00166 case REGISTERED: 00167 if (server_assignment_store_data) 00168 assignment_type = AVP_IMS_SAR_TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME; 00169 else assignment_type = AVP_IMS_SAR_TIMEOUT_DEREGISTRATION; 00170 sar_res = SAR(0,cscf_get_realm_from_uri(p->aor),p->aor,p->s->private_identity,assignment_type,0); 00171 00172 if (sar_res==1){ 00173 /* SAR successful, de-register everything in this implicit set */ 00174 if (!p->s){ 00175 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Problem r_public does not contain IMS Subscription <%.*s> \n", 00176 p->aor.len,p->aor.s); 00177 break; 00178 } 00179 for(j=0;j<p->s->service_profiles_cnt;j++) 00180 for(n=0;n<p->s->service_profiles[j].public_identities_cnt;n++){ 00181 pi = &(p->s->service_profiles[j].public_identities[n]); 00182 if (pi->public_identity.len == p->aor.len && 00183 strncasecmp(pi->public_identity.s,p->aor.s,p->aor.len)==0) continue; 00184 rpublic = get_r_public_previous_lock(pi->public_identity,p->hash); 00185 00186 if(!rpublic){ 00187 LOG(L_INFO,"INFO:"M_NAME":registrar_timer: The implicit set public identity <%.*s> was not found in the registrar", 00188 pi->public_identity.len,pi->public_identity.s); 00189 continue; 00190 } 00191 rpublic_hash = rpublic->hash; 00192 00193 c2 = rpublic->head; 00194 while(c2){ 00195 cn2 = c2->next; 00196 if (!r_valid_contact(c2)){ 00197 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Contact <%.*s> expired and removed (because of implicit set).\n",c2->uri.len,c2->uri.s); 00198 S_event_reg(rpublic,c2,0,IMS_REGISTRAR_CONTACT_EXPIRED,1);/* send now because we might drop the dialog soon */ 00199 del_r_contact(rpublic,c2); 00200 } 00201 c2 = cn2; 00202 } 00203 00204 s2 = rpublic->shead; 00205 while(s2){ 00206 sn2 = s2->next; 00207 if (!r_valid_subscriber(s2)){ 00208 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: Subscriber <%.*s> expired and removed (because of implicit set).\n",s2->subscriber.len,s2->subscriber.s); 00209 del_r_subscriber(rpublic,s2); 00210 } 00211 s2 = sn2; 00212 } 00213 00214 if (!rpublic->head){/* no more contacts, then deregister it */ 00215 if (!rpublic->shead) {/* delete it if there are no more subscribers for it */ 00216 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> removed (because of implicit set).\n", 00217 rpublic->aor.len,rpublic->aor.s); 00218 del_r_public(rpublic); 00219 }else{/* else mark it unregistered - to avoid more SAR */ 00220 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> kept unregistered - has subscribers (because of implicit set).\n", 00221 rpublic->aor.len,rpublic->aor.s); 00222 rpublic->reg_state = NOT_REGISTERED; 00223 } 00224 } 00225 /* because the lock was taken with a previous lock */ 00226 if (rpublic_hash!=i) r_unlock(rpublic_hash); 00227 } 00228 00229 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> deregistered.\n", 00230 p->aor.len,p->aor.s); 00231 if (!p->shead) {/* delete it if there are no more subscribers for it */ 00232 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> removed.\n", 00233 p->aor.len,p->aor.s); 00234 del_r_public(p); 00235 }else{/* else mark it unregistered - to avoid more SAR */ 00236 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> kept unregistered - has subscribers.\n", 00237 p->aor.len,p->aor.s); 00238 p->reg_state = NOT_REGISTERED; 00239 } 00240 }else{ 00241 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> deregistration SAR failed.Keeping into registrar, but with no contacts\n", 00242 p->aor.len,p->aor.s); 00243 #ifdef WITH_IMS_PM 00244 impu_cnt++; 00245 #endif 00246 } 00247 break; 00248 00249 case UNREGISTERED: 00250 /* Don't drop it, just keep it for unregistered triggering*/ 00251 #ifdef WITH_IMS_PM 00252 impu_cnt++; 00253 #endif 00254 break; 00255 00256 case NOT_REGISTERED: 00257 /* to avoid sending SAR when we still have subscribers, but no contact */ 00258 if (!p->shead) {/* delete it if there are no more subscribers for it */ 00259 LOG(L_DBG,"DBG:"M_NAME":registrar_timer: User <%.*s> removed - no more subscribers.\n", 00260 p->aor.len,p->aor.s); 00261 del_r_public(p); 00262 } 00263 break; 00264 } 00265 } 00266 #ifdef WITH_IMS_PM 00267 else impu_cnt++; 00268 #endif 00269 p = pn; 00270 } 00271 r_unlock(i); 00272 } 00273 print_r(L_INFO); 00274 #ifdef WITH_IMS_PM 00275 IMS_PM_LOG01(RD_NbrIMPU,impu_cnt); 00276 IMS_PM_LOG01(RD_NbrContact,contact_cnt); 00277 IMS_PM_LOG01(RD_NbrSubs,subs_cnt); 00278 #endif 00279 }
| 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 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 }
| static int r_calc_expires | ( | contact_t * | c, | |
| unsigned int | expires_hdr | |||
| ) | [inline, static] |
Calculates the expiration time for one contact.
Tries to use the Expiration header, if not present then use the expires parameter of the contact, if param not present it defaults to the default value. Also checks
| c | - the contact to calcualte for | |
| expires_hdr | - value of expires hdr if present, if not -1 |
Definition at line 599 of file registrar.c.
References registration_default_expires, registration_max_expires, registration_min_expires, and time_now.
00600 { 00601 unsigned int r; 00602 if (expires_hdr>=0) r = expires_hdr; 00603 else r = registration_default_expires; 00604 if (c && c->expires) 00605 str2int(&(c->expires->body), (unsigned int*)&r); 00606 if (r>0 && r<registration_min_expires) r = registration_min_expires; 00607 if (r>registration_max_expires) r = registration_max_expires; 00608 return time_now+r; 00609 }
| int r_calc_contact_q | ( | param_t * | _q, | |
| qvalue_t * | _r | |||
| ) |
Definition at line 616 of file registrar.c.
Referenced by update_contacts().
00617 { 00618 if (!_q || (_q->body.len == 0)) { 00619 *_r = -1; 00620 } else { 00621 if (str2q(_r, _q->body.s, _q->body.len) < 0) { 00622 LOG(L_ERR, "r_calc_contact_q(): Invalid q parameter\n"); 00623 return -1; 00624 } 00625 } 00626 return 0; 00627 }
| static int r_add_contact | ( | struct sip_msg * | msg, | |
| str | uri, | |||
| int | expires, | |||
| qvalue_t | qvalue | |||
| ) | [static] |
Adds a Contact header to the reply, containing the approved expires.
| msg | - the SIP message to add contact header to its reply | |
| uri | - the contact uri | |
| expires | - the expiration time | |
| qvalue | - q-value |
Definition at line 637 of file registrar.c.
References cscf_add_header_rpl().
00638 { 00639 str hdr; 00640 int r; 00641 hdr.s = pkg_malloc(10+uri.len+10+12+3+1); 00642 if (!hdr.s) return 0; 00643 if(qvalue != -1) { 00644 float q = (float)qvalue/1000; 00645 sprintf(hdr.s,"Contact: <%.*s>;expires=%d;q=%.3f\r\n",uri.len,uri.s,expires,q); 00646 } 00647 else 00648 sprintf(hdr.s,"Contact: <%.*s>;expires=%d\r\n",uri.len,uri.s,expires); 00649 hdr.len = strlen(hdr.s); 00650 r = cscf_add_header_rpl(msg,&hdr); 00651 pkg_free(hdr.s); 00652 return r; 00653 }
| static int update_contacts | ( | struct sip_msg * | msg, | |
| int | assignment_type, | |||
| unsigned char | is_star, | |||
| ims_subscription ** | s, | |||
| str * | ua, | |||
| str * | path, | |||
| str * | ccf1, | |||
| str * | ccf2, | |||
| str * | ecf1, | |||
| str * | ecf2 | |||
| ) | [inline, static] |
Updates the contacts in the registrar with the new values received, for the addresses received in the SAA.
| msg | - the SIP REGISTER message, if available | |
| assignment_type | - the value sent in SAR | |
| ct | - SIP contact list from message | |
| is_star | - if the contact header was of type STAR | |
| s | - the ims_subscription received in the SAA | |
| ua | - the user agent string | |
| path | - the path to save |
Definition at line 669 of file registrar.c.
References AVP_IMS_SAR_REGISTRATION, ims_public_identity::barring, ci, cscf_get_expires_hdr(), cscf_get_last_via_received(), cscf_get_last_via_sent_by(), _r_public::early_ims_ip, if, IMS_REGISTRAR_CONTACT_REFRESHED, IMS_REGISTRAR_CONTACT_REGISTERED, IMS_USER_REGISTERED, M_NAME, ims_public_identity::public_identity, r_act_time(), r_calc_contact_q(), r_calc_expires(), registration_disable_early_ims, S_event_reg(), STR_SHM_DUP, update_r_contact(), and update_r_public().
00671 { 00672 int i,j,s_used=0; 00673 r_public *p,*rpublic; 00674 r_contact *c=0; 00675 ims_public_identity *pi=0; 00676 struct hdr_field *h; 00677 contact_t *ci; 00678 int reg_state,expires_hdr=-1,expires,hash,rpublic_hash; 00679 str public_identity,sent_by={0,0}; 00680 int contacts_added=0; 00681 qvalue_t qvalue; 00682 00683 // if (!*s) return 1; 00684 if (msg) { 00685 /* check for Early-IMS case */ 00686 if (!registration_disable_early_ims && !msg->authorization){ 00687 str received={0,0}; 00688 sent_by = cscf_get_last_via_sent_by(msg); 00689 if (sent_by.len){ 00690 received = cscf_get_last_via_received(msg); 00691 if (received.len) sent_by=received; 00692 } 00693 } 00694 expires_hdr = cscf_get_expires_hdr(msg); 00695 } 00696 00697 r_act_time(); 00698 LOG(L_DBG,"DBG:"M_NAME":update_contacts: Assign Type %d\n",assignment_type); 00699 switch (assignment_type){ 00700 case AVP_IMS_SAR_REGISTRATION: 00701 reg_state = IMS_USER_REGISTERED; 00702 if (!*s) break; 00703 for(i=0;i<(*s)->service_profiles_cnt;i++) 00704 for(j=0;j<(*s)->service_profiles[i].public_identities_cnt;j++){ 00705 pi = &((*s)->service_profiles[i].public_identities[j]); 00706 if (!pi->