00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00056 #include <time.h>
00057
00058 #include "../../parser/contact/contact.h"
00059 #include "../../parser/contact/parse_contact.h"
00060 #include "../../ut.h"
00061 #include "../tm/tm_load.h"
00062 #include "../cdp/cdp_load.h"
00063 #include "../../dset.h"
00064
00065 #include "registrar.h"
00066 #include "registration.h"
00067 #include "mod.h"
00068 #include "registrar_parser.h"
00069 #include "registrar_storage.h"
00070 #include "sip.h"
00071 #include "cx.h"
00072 #include "cx_avp.h"
00073 #include "sip_messages.h"
00074 #include "dlg_state.h"
00075
00076
00077 extern struct tm_binds tmb;
00078 extern struct cdp_binds cdpb;
00080 extern int r_hash_size;
00081 extern r_hash_slot *registrar;
00083 extern str scscf_name_str;
00084 extern str scscf_service_route_uri;
00085 extern str scscf_registration_min_expires;
00086 extern int server_assignment_store_data;
00089 extern int registration_default_expires;
00090 extern int registration_min_expires;
00091 extern int registration_max_expires;
00092 extern int registration_disable_early_ims;
00094 extern time_t time_now;
00096 extern int append_branches;
00099 #ifdef WITH_IMS_PM
00100 static str zero={0,0};
00101 #endif
00102
00103
00109 void registrar_timer(unsigned int ticks, void* param)
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);
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){
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
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);
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){
00215 if (!rpublic->shead) {
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{
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
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) {
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{
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
00251 #ifdef WITH_IMS_PM
00252 impu_cnt++;
00253 #endif
00254 break;
00255
00256 case NOT_REGISTERED:
00257
00258 if (!p->shead) {
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 }
00280
00302 int S_assign_server(struct sip_msg *msg,char *str1,char *str2 )
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
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
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
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
00391
00392
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 }
00407
00429 int S_assign_server_unreg(struct sip_msg *msg,char *str1,char *str2 )
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
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
00474
00475
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 }
00485
00486
00498 int SAR(struct sip_msg *msg, str realm, str public_identity, str private_identity,
00499 int assignment_type,int data_available)
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
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
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 }
00586
00587
00588
00599 static inline int r_calc_expires(contact_t *c,unsigned int expires_hdr)
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 }
00610
00611
00612
00613
00614
00615
00616 int r_calc_contact_q(param_t* _q, qvalue_t* _r)
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 }
00628
00637 static int r_add_contact(struct sip_msg *msg,str uri,int expires,qvalue_t qvalue)
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 }
00654
00655
00656
00669 static inline int update_contacts(struct sip_msg* msg, int assignment_type,
00670 unsigned char is_star, ims_subscription **s, str* ua,str *path, str *ccf1,str *ccf2,str *ecf1,str *ecf2)
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
00684 if (msg) {
00685
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->barring){
00707 if (!(p=update_r_public(pi->public_identity,®_state,s,ccf1,ccf2,ecf1,ecf2))){
00708 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00709 pi->public_identity.len,pi->public_identity.s);
00710 goto error;
00711 }
00712 s_used++;
00713 if (!registration_disable_early_ims && sent_by.len) {
00714 if (p->early_ims_ip.s) shm_free(p->early_ims_ip.s);
00715 STR_SHM_DUP(p->early_ims_ip,sent_by,"IP Early IMS");
00716 }
00717 if (is_star){
00718 LOG(L_ERR,"ERR:"M_NAME":update_contacts: STAR not accepted in contact for Registration.\n");
00719 }else{
00720 for(h=msg->contact;h;h=h->next)
00721 if (h->type==HDR_CONTACT_T && h->parsed)
00722 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){
00723 if(r_calc_contact_q(ci->q, &qvalue) != 0){
00724 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00725 ci->uri.len,ci->uri.s);
00726 goto error;
00727 }
00728 expires = r_calc_expires(ci,expires_hdr);
00729 if (!(c=update_r_contact(p,ci->uri,&expires,ua,path,qvalue))){
00730 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00731 ci->uri.len,ci->uri.s);
00732 goto error;
00733 }
00734 if (assignment_type == AVP_IMS_SAR_REGISTRATION)
00735 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_REGISTERED,0);
00736 else
00737 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_REFRESHED,0);
00738
00739 }
00740 if (!contacts_added){
00741 for(c=p->head;c;c=c->next)
00742 r_add_contact(msg,c->uri,c->expires-time_now,c->qvalue);
00743 contacts_added = 1;
00744 }
00745 }
00746 r_unlock(p->hash);
00747 }
00748 }
00749 break;
00750 case AVP_IMS_SAR_RE_REGISTRATION:
00751 reg_state = IMS_USER_REGISTERED;
00752 public_identity = cscf_get_public_identity(msg);
00753 if (!public_identity.len) {
00754 LOG(L_ERR,"ERR:"M_NAME":update_contacts: message contains no public identity\n");
00755 goto error;
00756 }
00757
00758 p = get_r_public(public_identity);
00759 if (!p){
00760 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s> - not found in registrar\n",
00761 public_identity.len,public_identity.s);
00762 goto error;
00763 }
00764
00765 if (!registration_disable_early_ims && sent_by.len) {
00766 if (p->early_ims_ip.s) shm_free(p->early_ims_ip.s);
00767 STR_SHM_DUP(p->early_ims_ip,sent_by,"IP Early IMS");
00768 }
00769 if (is_star){
00770 LOG(L_ERR,"ERR:"M_NAME":update_contacts: STAR not accepted in contact for Re-Registration.\n");
00771 }else{
00772 for(h=msg->contact;h;h=h->next)
00773 if (h->type==HDR_CONTACT_T && h->parsed)
00774 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){
00775 if(r_calc_contact_q(ci->q, &qvalue) != 0){
00776 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00777 ci->uri.len,ci->uri.s);
00778 goto error;
00779 }
00780 expires = r_calc_expires(ci,expires_hdr);
00781 if (!(c=update_r_contact(p,ci->uri,&expires,ua,path,qvalue))){
00782 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00783 ci->uri.len,ci->uri.s);
00784 goto error;
00785 }
00786 if (assignment_type == AVP_IMS_SAR_REGISTRATION)
00787 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_REGISTERED,0);
00788 else
00789 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_REFRESHED,0);
00790 }
00791 for(c=p->head;c;c=c->next)
00792 r_add_contact(msg,c->uri,c->expires-time_now,c->qvalue);
00793 }
00794
00795
00796 if (p->s)
00797 for(i=0;i<p->s->service_profiles_cnt;i++)
00798 for(j=0;j<p->s->service_profiles[i].public_identities_cnt;j++){
00799 pi = &(p->s->service_profiles[i].public_identities[j]);
00800 if (public_identity.len==pi->public_identity.len &&
00801 strncasecmp(pi->public_identity.s,public_identity.s,public_identity.len)==0) continue;
00802
00803 rpublic = update_r_public_previous_lock(pi->public_identity,p->hash,®_state,s,ccf1,ccf2,ecf1,ecf2);
00804 if (!rpublic){
00805 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00806 pi->public_identity.len,pi->public_identity.s);
00807 continue;
00808 }
00809
00810 if (!registration_disable_early_ims && sent_by.len) {
00811 if (rpublic->early_ims_ip.s) shm_free(rpublic->early_ims_ip.s);
00812 STR_SHM_DUP(rpublic->early_ims_ip,sent_by,"IP Early IMS");
00813 }
00814 if (is_star){
00815 LOG(L_ERR,"ERR:"M_NAME":update_contacts: STAR not accepted in contact for Re-Registration.\n");
00816 }else{
00817 for(h=msg->contact;h;h=h->next)
00818 if (h->type==HDR_CONTACT_T && h->parsed)
00819 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){
00820 if(r_calc_contact_q(ci->q, &qvalue) != 0){
00821 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00822 ci->uri.len,ci->uri.s);
00823 goto error;
00824 }
00825 expires = r_calc_expires(ci,expires_hdr);
00826 if (!(c=update_r_contact(rpublic,ci->uri,&expires,ua,path,qvalue))){
00827 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s> - implicit identity not found in registrar\n",
00828 ci->uri.len,ci->uri.s);
00829 goto error;
00830 }
00831 if (assignment_type == AVP_IMS_SAR_REGISTRATION)
00832 S_event_reg(rpublic,c,0,IMS_REGISTRAR_CONTACT_REGISTERED,0);
00833 else
00834 S_event_reg(rpublic,c,0,IMS_REGISTRAR_CONTACT_REFRESHED,0);
00835 }
00836 }
00837 if (rpublic->hash!=p->hash) r_unlock(rpublic->hash);
00838 }
00839 r_unlock(p->hash);
00840 break;
00841
00842 case AVP_IMS_SAR_USER_DEREGISTRATION:
00843 public_identity = cscf_get_public_identity(msg);
00844 if (!public_identity.len) {
00845 LOG(L_ERR,"ERR:"M_NAME":update_contacts: message contains no public identity\n");
00846 goto error;
00847 }
00848 p = get_r_public(public_identity);
00849
00850 if (!p){
00851 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s> - not found in registrar\n",
00852 public_identity.len,public_identity.s);
00853 goto error;
00854 }
00855
00856
00857 if (is_star){
00858 c = p->head;
00859 while(c){
00860 c->expires = time_now;
00861 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_UNREGISTERED,0);
00862 r_add_contact(msg,c->uri,0,c->qvalue);
00863 del_r_contact(p,c);
00864 c = c->next;
00865 }
00866 }else{
00867 for(h=msg->contact;h;h=h->next)
00868 if (h->type==HDR_CONTACT_T && h->parsed)
00869 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){
00870 c = get_r_contact(p,ci->uri);
00871 if (c) {
00872 c->expires = time_now;
00873 S_event_reg(p,c,0,IMS_REGISTRAR_CONTACT_UNREGISTERED,0);
00874 r_add_contact(msg,c->uri,0,c->qvalue);
00875 del_r_contact(p,c);
00876 }
00877 }
00878 for(c=p->head;c;c=c->next)
00879 r_add_contact(msg,c->uri,c->expires-time_now,c->qvalue);
00880 }
00881
00882
00883 if (p->s)
00884 for(i=0;i<p->s->service_profiles_cnt;i++)
00885 for(j=0;j<p->s->service_profiles[i].public_identities_cnt;j++){
00886 pi = &(p->s->service_profiles[i].public_identities[j]);
00887 if (public_identity.len == pi->public_identity.len &&
00888 strncasecmp(pi->public_identity.s,public_identity.s,public_identity.len)==0) continue;
00889
00890 rpublic = update_r_public_previous_lock(pi->public_identity,p->hash,®_state,s,ccf1,ccf2,ecf1,ecf2);
00891 if (!rpublic){
00892 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s> - implicit identity not found in registrar\n",
00893 pi->public_identity.len,pi->public_identity.s);
00894 continue;
00895 }
00896 s_used++;
00897 if (is_star){
00898 c = rpublic->head;
00899 while(c){
00900 c->expires = time_now;
00901 S_event_reg(rpublic,c,0,IMS_REGISTRAR_CONTACT_UNREGISTERED,0);
00902 del_r_contact(rpublic,c);
00903 c = c->next;
00904 }
00905 }else{
00906 for(h=msg->contact;h;h=h->next)
00907 if (h->type==HDR_CONTACT_T && h->parsed)
00908 for(ci=((contact_body_t*)h->parsed)->contacts;ci;ci=ci->next){
00909 c = get_r_contact(rpublic,ci->uri);
00910 if (c) {
00911 c->expires = time_now;
00912 S_event_reg(rpublic,c,0,IMS_REGISTRAR_CONTACT_UNREGISTERED,0);
00913 del_r_contact(rpublic,c);
00914 }
00915 }
00916 }
00917 rpublic_hash = rpublic->hash;
00918 if (!rpublic->head)
00919 del_r_public(rpublic);
00920
00921 if (p->hash!=rpublic_hash) r_unlock(rpublic_hash);
00922 }
00923
00924 hash = p->hash;
00925 if (!p->head)
00926 del_r_public(p);
00927 r_unlock(hash);
00928 break;
00929
00930 case AVP_IMS_SAR_UNREGISTERED_USER:
00931 reg_state = IMS_USER_UNREGISTERED;
00932 r_act_time();
00933 if (!*s) break;
00934 for(i=0;i<(*s)->service_profiles_cnt;i++)
00935 for(j=0;j<(*s)->service_profiles[i].public_identities_cnt;j++){
00936 pi = &((*s)->service_profiles[i].public_identities[j]);
00937 if (!pi->barring){
00938 if (!(p=update_r_public(pi->public_identity,®_state,s,ccf1,ccf2,ecf1,ecf2))){
00939 LOG(L_ERR,"ERR:"M_NAME":update_contacts: error on <%.*s>\n",
00940 pi->public_identity.len,pi->public_identity.s);
00941