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 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include "../../mem/shm_mem.h"
00037 #include "../../dprint.h"
00038 #include "../../str.h"
00039 #include "../pua/hash.h"
00040 #include "presence.h"
00041 #include "hash.h"
00042 #include "notify.h"
00043
00044 shtable_t new_shtable(int hash_size)
00045 {
00046 shtable_t htable= NULL;
00047 int i, j;
00048
00049 i = 0;
00050 htable= (subs_entry_t*)shm_malloc(hash_size* sizeof(subs_entry_t));
00051 if(htable== NULL)
00052 {
00053 ERR_MEM(SHARE_MEM);
00054 }
00055 memset(htable, 0, hash_size* sizeof(subs_entry_t));
00056 for(i= 0; i< hash_size; i++)
00057 {
00058 if(lock_init(&htable[i].lock)== 0)
00059 {
00060 LM_ERR("initializing lock [%d]\n", i);
00061 goto error;
00062 }
00063 htable[i].entries= (subs_t*)shm_malloc(sizeof(subs_t));
00064 if(htable[i].entries== NULL)
00065 {
00066 lock_destroy(&htable[i].lock);
00067 ERR_MEM(SHARE_MEM);
00068 }
00069 memset(htable[i].entries, 0, sizeof(subs_t));
00070 htable[i].entries->next= NULL;
00071 }
00072
00073 return htable;
00074
00075 error:
00076 if(htable)
00077 {
00078 for(j=0; j< i; j++)
00079 {
00080 lock_destroy(&htable[j].lock);
00081 shm_free(htable[j].entries);
00082 }
00083 shm_free(htable);
00084 }
00085 return NULL;
00086
00087 }
00088
00089 void destroy_shtable(shtable_t htable, int hash_size)
00090 {
00091 int i;
00092
00093 if(htable== NULL)
00094 return;
00095
00096 for(i= 0; i< hash_size; i++)
00097 {
00098 lock_destroy(&htable[i].lock);
00099 free_subs_list(htable[i].entries->next, SHM_MEM_TYPE, 1);
00100 shm_free(htable[i].entries);
00101 }
00102 shm_free(htable);
00103 htable= NULL;
00104 }
00105
00106 subs_t* search_shtable(shtable_t htable,str callid,str to_tag,
00107 str from_tag,unsigned int hash_code)
00108 {
00109 subs_t* s;
00110
00111 s= htable[hash_code].entries->next;
00112
00113 while(s)
00114 {
00115 if(s->callid.len==callid.len &&
00116 strncmp(s->callid.s, callid.s, callid.len)==0 &&
00117 s->to_tag.len== to_tag.len &&
00118 strncmp(s->to_tag.s, to_tag.s, to_tag.len)==0 &&
00119 s->from_tag.len== from_tag.len &&
00120 strncmp(s->from_tag.s, from_tag.s, from_tag.len)== 0)
00121 return s;
00122 s= s->next;
00123 }
00124
00125 return NULL;
00126 }
00127
00128 subs_t* mem_copy_subs(subs_t* s, int mem_type)
00129 {
00130 int size;
00131 subs_t* dest;
00132
00133 size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
00134 + s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
00135 + s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len
00136 + s->local_contact.len+ s->contact.len+ s->record_route.len+
00137 + s->reason.len+ 1)*sizeof(char);
00138
00139 if(mem_type & PKG_MEM_TYPE)
00140 dest= (subs_t*)pkg_malloc(size);
00141 else
00142 dest= (subs_t*)shm_malloc(size);
00143
00144 if(dest== NULL)
00145 {
00146 ERR_MEM((mem_type==PKG_MEM_TYPE)?PKG_MEM_STR:SHARE_MEM);
00147 }
00148 memset(dest, 0, size);
00149 size= sizeof(subs_t);
00150
00151 CONT_COPY(dest, dest->pres_uri, s->pres_uri)
00152 CONT_COPY(dest, dest->to_user, s->to_user)
00153 CONT_COPY(dest, dest->to_domain, s->to_domain)
00154 CONT_COPY(dest, dest->from_user, s->from_user)
00155 CONT_COPY(dest, dest->from_domain, s->from_domain)
00156 CONT_COPY(dest, dest->to_tag, s->to_tag)
00157 CONT_COPY(dest, dest->from_tag, s->from_tag)
00158 CONT_COPY(dest, dest->callid, s->callid)
00159 CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
00160 CONT_COPY(dest, dest->local_contact, s->local_contact)
00161 CONT_COPY(dest, dest->contact, s->contact)
00162 CONT_COPY(dest, dest->record_route, s->record_route)
00163 if(s->event_id.s)
00164 CONT_COPY(dest, dest->event_id, s->event_id)
00165 if(s->reason.s)
00166 CONT_COPY(dest, dest->reason, s->reason)
00167
00168 dest->event= s->event;
00169 dest->local_cseq= s->local_cseq;
00170 dest->remote_cseq= s->remote_cseq;
00171 dest->status= s->status;
00172 dest->version= s->version;
00173 dest->send_on_cback= s->send_on_cback;
00174 dest->expires= s->expires;
00175 dest->db_flag= s->db_flag;
00176
00177 return dest;
00178
00179 error:
00180 if(dest)
00181 {
00182 if(mem_type & PKG_MEM_TYPE)
00183 pkg_free(dest);
00184 else
00185 shm_free(dest);
00186 }
00187 return NULL;
00188 }
00189
00190
00191 subs_t* mem_copy_subs_noc(subs_t* s)
00192 {
00193 int size;
00194 subs_t* dest;
00195
00196 size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len
00197 + s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len
00198 + s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len
00199 + s->local_contact.len + s->record_route.len+
00200 + s->reason.len+ 1)*sizeof(char);
00201
00202 dest= (subs_t*)shm_malloc(size);
00203 if(dest== NULL)
00204 {
00205 ERR_MEM(SHARE_MEM);
00206 }
00207 memset(dest, 0, size);
00208 size= sizeof(subs_t);
00209
00210 CONT_COPY(dest, dest->pres_uri, s->pres_uri)
00211 CONT_COPY(dest, dest->to_user, s->to_user)
00212 CONT_COPY(dest, dest->to_domain, s->to_domain)
00213 CONT_COPY(dest, dest->from_user, s->from_user)
00214 CONT_COPY(dest, dest->from_domain, s->from_domain)
00215 CONT_COPY(dest, dest->to_tag, s->to_tag)
00216 CONT_COPY(dest, dest->from_tag, s->from_tag)
00217 CONT_COPY(dest, dest->callid, s->callid)
00218 CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str)
00219 CONT_COPY(dest, dest->local_contact, s->local_contact)
00220 CONT_COPY(dest, dest->record_route, s->record_route)
00221 if(s->event_id.s)
00222 CONT_COPY(dest, dest->event_id, s->event_id)
00223 if(s->reason.s)
00224 CONT_COPY(dest, dest->reason, s->reason)
00225
00226 dest->event= s->event;
00227 dest->local_cseq= s->local_cseq;
00228 dest->remote_cseq= s->remote_cseq;
00229 dest->status= s->status;
00230 dest->version= s->version;
00231 dest->send_on_cback= s->send_on_cback;
00232 dest->expires= s->expires;
00233 dest->db_flag= s->db_flag;
00234
00235 dest->contact.s= (char*)shm_malloc(s->contact.len* sizeof(char));
00236 if(dest->contact.s== NULL)
00237 {
00238 ERR_MEM(SHARE_MEM);
00239 }
00240 memcpy(dest->contact.s, s->contact.s, s->contact.len);
00241 dest->contact.len= s->contact.len;
00242
00243 return dest;
00244
00245 error:
00246 if(dest)
00247 shm_free(dest);
00248 return NULL;
00249 }
00250
00251 int insert_shtable(shtable_t htable,unsigned int hash_code, subs_t* subs)
00252 {
00253 subs_t* new_rec= NULL;
00254
00255 new_rec= mem_copy_subs_noc(subs);
00256 if(new_rec== NULL)
00257 {
00258 LM_ERR("copying in share memory a subs_t structure\n");
00259 goto error;
00260 }
00261
00262 new_rec->expires+= (int)time(NULL);
00263 new_rec->db_flag= INSERTDB_FLAG;
00264
00265 lock_get(&htable[hash_code].lock);
00266
00267 new_rec->next= htable[hash_code].entries->next;
00268
00269 htable[hash_code].entries->next= new_rec;
00270
00271 lock_release(&htable[hash_code].lock);
00272
00273 return 0;
00274
00275 error:
00276 if(new_rec)
00277 shm_free(new_rec);
00278 return -1;
00279 }
00280
00281 int delete_shtable(shtable_t htable,unsigned int hash_code,str to_tag)
00282 {
00283 subs_t* s= NULL, *ps= NULL;
00284 int found= -1;
00285
00286 lock_get(&htable[hash_code].lock);
00287
00288 ps= htable[hash_code].entries;
00289 s= ps->next;
00290
00291 while(s)
00292 {
00293 if(s->to_tag.len== to_tag.len &&
00294 strncmp(s->to_tag.s, to_tag.s, to_tag.len)== 0)
00295 {
00296 found= s->local_cseq;
00297 ps->next= s->next;
00298 if(s->contact.s!=NULL)
00299 shm_free(s->contact.s);
00300 shm_free(s);
00301 break;
00302 }
00303 ps= s;
00304 s= s->next;
00305 }
00306 lock_release(&htable[hash_code].lock);
00307 return found;
00308 }
00309
00310 void free_subs_list(subs_t* s_array, int mem_type, int ic)
00311 {
00312 subs_t* s;
00313
00314 while(s_array)
00315 {
00316 s= s_array;
00317 s_array= s_array->next;
00318 if(mem_type & PKG_MEM_TYPE)
00319 {
00320 if(ic)
00321 pkg_free(s->contact.s);
00322 pkg_free(s);
00323 }
00324 else
00325 {
00326 if(ic)
00327 shm_free(s->contact.s);
00328 shm_free(s);
00329 }
00330 }
00331
00332 }
00333
00334 int update_shtable(shtable_t htable,unsigned int hash_code,
00335 subs_t* subs, int type)
00336 {
00337 subs_t* s;
00338
00339 lock_get(&htable[hash_code].lock);
00340
00341 s= search_shtable(htable,subs->callid, subs->to_tag, subs->from_tag,
00342 hash_code);
00343 if(s== NULL)
00344 {
00345 LM_DBG("record not found in hash table\n");
00346 lock_release(&htable[hash_code].lock);
00347 return -1;
00348 }
00349
00350 if(type & REMOTE_TYPE)
00351 {
00352 s->expires= subs->expires+ (int)time(NULL);
00353 s->remote_cseq= subs->remote_cseq;
00354 }
00355 else
00356 {
00357 subs->local_cseq= s->local_cseq;
00358 s->local_cseq++;
00359 s->version= subs->version+ 1;
00360 }
00361
00362 if(strncmp(s->contact.s, subs->contact.s, subs->contact.len))
00363 {
00364 shm_free(s->contact.s);
00365 s->contact.s= (char*)shm_malloc(subs->contact.len* sizeof(char));
00366 if(s->contact.s== NULL)
00367 {
00368 lock_release(&htable[hash_code].lock);
00369 LM_ERR("no more shared memory\n");
00370 return -1;
00371 }
00372 memcpy(s->contact.s, subs->contact.s, subs->contact.len);
00373 s->contact.len= subs->contact.len;
00374 }
00375
00376 s->status= subs->status;
00377 s->event= subs->event;
00378 subs->db_flag= s->db_flag;
00379
00380 if(s->db_flag & NO_UPDATEDB_FLAG)
00381 s->db_flag= UPDATEDB_FLAG;
00382
00383 lock_release(&htable[hash_code].lock);
00384
00385 return 0;
00386 }
00387
00388 phtable_t* new_phtable(void)
00389 {
00390 phtable_t* htable= NULL;
00391 int i, j;
00392
00393 i = 0;
00394 htable= (phtable_t*)shm_malloc(phtable_size* sizeof(phtable_t));
00395 if(htable== NULL)
00396 {
00397 ERR_MEM(SHARE_MEM);
00398 }
00399 memset(htable, 0, phtable_size* sizeof(phtable_t));
00400
00401 for(i= 0; i< phtable_size; i++)
00402 {
00403 if(lock_init(&htable[i].lock)== 0)
00404 {
00405 LM_ERR("initializing lock [%d]\n", i);
00406 goto error;
00407 }
00408 htable[i].entries= (pres_entry_t*)shm_malloc(sizeof(pres_entry_t));
00409 if(htable[i].entries== NULL)
00410 {
00411 ERR_MEM(SHARE_MEM);
00412 }
00413 memset(htable[i].entries, 0, sizeof(pres_entry_t));
00414 htable[i].entries->next= NULL;
00415 }
00416
00417 return htable;
00418
00419 error:
00420 if(htable)
00421 {
00422 for(j=0; j< i; j++)
00423 {
00424 if(htable[i].entries)
00425 shm_free(htable[i].entries);
00426 else
00427 break;
00428 lock_destroy(&htable[i].lock);
00429 }
00430 shm_free(htable);
00431 }
00432 return NULL;
00433
00434 }
00435
00436 void destroy_phtable(void)
00437 {
00438 int i;
00439 pres_entry_t* p, *prev_p;
00440
00441 if(pres_htable== NULL)
00442 return;
00443
00444 for(i= 0; i< phtable_size; i++)
00445 {
00446 lock_destroy(&pres_htable[i].lock);
00447 p= pres_htable[i].entries;
00448 while(p)
00449 {
00450 prev_p= p;
00451 p= p->next;
00452 if(prev_p->sphere)
00453 shm_free(prev_p->sphere);
00454 shm_free(prev_p);
00455 }
00456 }
00457 shm_free(pres_htable);
00458 }
00459
00460
00461 pres_entry_t* search_phtable(str* pres_uri,int event, unsigned int hash_code)
00462 {
00463 pres_entry_t* p;
00464
00465 LM_DBG("pres_uri= %.*s\n", pres_uri->len, pres_uri->s);
00466 p= pres_htable[hash_code].entries->next;
00467 while(p)
00468 {
00469 if(p->event== event && p->pres_uri.len== pres_uri->len &&
00470 strncmp(p->pres_uri.s, pres_uri->s, pres_uri->len)== 0 )
00471 return p;
00472 p= p->next;
00473 }
00474 return NULL;
00475 }
00476
00477 int insert_phtable(str* pres_uri, int event, char* sphere)
00478 {
00479 unsigned int hash_code;
00480 pres_entry_t* p= NULL;
00481 int size;
00482
00483 hash_code= core_hash(pres_uri, NULL, phtable_size);
00484
00485 lock_get(&pres_htable[hash_code].lock);
00486
00487 p= search_phtable(pres_uri, event, hash_code);
00488 if(p)
00489 {
00490 p->publ_count++;
00491 lock_release(&pres_htable[hash_code].lock);
00492 return 0;
00493 }
00494 size= sizeof(pres_entry_t)+ pres_uri->len* sizeof(char);
00495
00496 p= (pres_entry_t*)shm_malloc(size);
00497 if(p== NULL)
00498 {
00499 lock_release(&pres_htable[hash_code].lock);
00500 ERR_MEM(SHARE_MEM);
00501 }
00502 memset(p, 0, size);
00503
00504 size= sizeof(pres_entry_t);
00505 p->pres_uri.s= (char*)p+ size;
00506 memcpy(p->pres_uri.s, pres_uri->s, pres_uri->len);
00507 p->pres_uri.len= pres_uri->len;
00508
00509 if(sphere)
00510 {
00511 p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char));
00512 if(p->sphere== NULL)
00513 {
00514 lock_release(&pres_htable[hash_code].lock);
00515 ERR_MEM(SHARE_MEM);
00516 }
00517 strcpy(p->sphere, sphere);
00518 }
00519
00520 p->event= event;
00521
00522
00523 p->next= pres_htable[hash_code].entries->next;
00524 pres_htable[hash_code].entries->next= p;
00525
00526 lock_release(&pres_htable[hash_code].lock);
00527
00528 return 0;
00529
00530 error:
00531 return -1;
00532 }
00533
00534 int delete_phtable(str* pres_uri, int event)
00535 {
00536 unsigned int hash_code;
00537 pres_entry_t* p= NULL, *prev_p= NULL;
00538
00539 hash_code= core_hash(pres_uri, NULL, phtable_size);
00540
00541 lock_get(&pres_htable[hash_code].lock);
00542
00543 p= search_phtable(pres_uri, event, hash_code);
00544 if(p== NULL)
00545 {
00546 LM_DBG("record not found\n");
00547 lock_release(&pres_htable[hash_code].lock);
00548 return 0;
00549 }
00550
00551 p->publ_count--;
00552 if(p->publ_count== 0)
00553 {
00554
00555 prev_p= pres_htable[hash_code].entries;
00556 while(prev_p->next)
00557 {
00558 if(prev_p->next== p)
00559 break;
00560 prev_p= prev_p->next;
00561 }
00562 if(prev_p->next== NULL)
00563 {
00564 LM_ERR("record not found\n");
00565 lock_release(&pres_htable[hash_code].lock);
00566 return -1;
00567 }
00568 prev_p->next= p->next;
00569 if(p->sphere)
00570 shm_free(p->sphere);
00571
00572 shm_free(p);
00573 }
00574 lock_release(&pres_htable[hash_code].lock);
00575
00576 return 0;
00577 }
00578
00579 int update_phtable(presentity_t* presentity, str pres_uri, str body)
00580 {
00581 char* sphere= NULL;
00582 unsigned int hash_code;
00583 pres_entry_t* p;
00584 int ret= 0;
00585 str* xcap_doc= NULL;
00586
00587
00588 sphere= extract_sphere(body);
00589 if(sphere==NULL)
00590 {
00591 LM_DBG("no sphere defined in new body\n");
00592 return 0;
00593 }
00594
00595
00596 hash_code= core_hash(&pres_uri, NULL, phtable_size);
00597
00598 lock_get(&pres_htable[hash_code].lock);
00599
00600 p= search_phtable(&pres_uri, presentity->event->evp->parsed, hash_code);
00601 if(p== NULL)
00602 {
00603 lock_release(&pres_htable[hash_code].lock);
00604 goto done;
00605 }
00606
00607 if(p->sphere)
00608 {
00609 if(strcmp(p->sphere, sphere)!= 0)
00610 {
00611
00612 shm_free(p->sphere);
00613 }
00614 else
00615 {
00616
00617 lock_release(&pres_htable[hash_code].lock);
00618 pkg_free(sphere);
00619 return 0;
00620 }
00621
00622 }
00623
00624
00625 p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char));
00626 if(p->sphere== NULL)
00627 {
00628 lock_release(&pres_htable[hash_code].lock);
00629 ret= -1;
00630 goto done;
00631 }
00632 strcpy(p->sphere, sphere);
00633
00634 lock_release(&pres_htable[hash_code].lock);
00635
00636
00637
00638 if(presentity->event->get_rules_doc(&presentity->user, &presentity->domain,
00639 &xcap_doc)< 0)
00640 {
00641 LM_ERR("failed to retreive xcap document\n");
00642 ret= -1;
00643 goto done;
00644 }
00645
00646 update_watchers_status(pres_uri, presentity->event, xcap_doc);
00647
00648
00649 done:
00650
00651 if(xcap_doc)
00652 {
00653 if(xcap_doc->s)
00654 pkg_free(xcap_doc->s);
00655 pkg_free(xcap_doc);
00656 }
00657
00658 if(sphere)
00659 pkg_free(sphere);
00660 return ret;
00661 }