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 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029
00030 #include "../../mem/mem.h"
00031 #include "../../mem/shm_mem.h"
00032 #include "../../dprint.h"
00033 #include "../../hash_func.h"
00034 #include "../../parser/msg_parser.h"
00035 #include "../../parser/parse_from.h"
00036 #include "hash.h"
00037 #include "pua.h"
00038 #include "send_publish.h"
00039
00040 void print_ua_pres(ua_pres_t* p)
00041 {
00042 LM_DBG("\tpres_uri= %.*s len= %d\n", p->pres_uri->len, p->pres_uri->s, p->pres_uri->len);
00043 if(p->watcher_uri)
00044 {
00045 LM_DBG("\twatcher_uri= %.*s len= %d\n", p->watcher_uri->len, p->watcher_uri->s, p->watcher_uri->len);
00046 LM_DBG("\tcall_id= %.*s len= %d\n", p->call_id.len, p->call_id.s, p->call_id.len);
00047 LM_DBG("\tfrom_tag= %.*s len= %d\n", p->from_tag.len, p->from_tag.s, p->from_tag.len);
00048 LM_DBG("\tto_tag= %.*s len= %d\n", p->to_tag.len, p->to_tag.s, p->to_tag.len);
00049 LM_DBG("\tflag= %d\n", p->flag);
00050 LM_DBG("\tevent= %d\n", p->event);
00051 }
00052 else
00053 {
00054 LM_DBG("\tetag= %.*s - len= %d\n", p->etag.len, p->etag.s, p->etag.len);
00055 if(p->id.s)
00056 LM_DBG("\tid= %.*s\n", p->id.len, p->id.s);
00057 }
00058 LM_DBG("\texpires= %d\n", p->expires- (int)time(NULL));
00059 }
00060
00061 htable_t* new_htable(void)
00062 {
00063 htable_t* H= NULL;
00064 int i= 0, j;
00065
00066 H= (htable_t*)shm_malloc(sizeof(htable_t));
00067 if(H== NULL)
00068 {
00069 LM_ERR("No more memory\n");
00070 return NULL;
00071 }
00072 memset(H, 0, sizeof(htable_t));
00073
00074 H->p_records= (hash_entry_t*)shm_malloc(HASH_SIZE* sizeof(hash_entry_t));
00075 if(H->p_records== NULL)
00076 {
00077 LM_ERR("No more share memory\n");
00078 goto error;
00079 }
00080
00081 for(i=0; i<HASH_SIZE; i++)
00082 {
00083 if(lock_init(&H->p_records[i].lock)== 0)
00084 {
00085 LM_CRIT("initializing lock [%d]\n", i);
00086 goto error;
00087 }
00088 H->p_records[i].entity= (ua_pres_t*)shm_malloc(sizeof(ua_pres_t));
00089 if(H->p_records[i].entity== NULL)
00090 {
00091 LM_ERR("No more share memory\n");
00092 goto error;
00093 }
00094 H->p_records[i].entity->next= NULL;
00095 }
00096 return H;
00097
00098 error:
00099
00100 if(H->p_records)
00101 {
00102 for(j=0; j< i; j++)
00103 {
00104 if(H->p_records[j].entity)
00105 shm_free(H->p_records[j].entity);
00106 lock_destroy(&H->p_records[j].lock);
00107
00108 }
00109 shm_free(H->p_records);
00110 }
00111 shm_free(H);
00112 return NULL;
00113
00114 }
00115
00116 ua_pres_t* search_htable(ua_pres_t* pres, unsigned int hash_code)
00117 {
00118 ua_pres_t* p= NULL,* L= NULL;
00119
00120 L= HashT->p_records[hash_code].entity;
00121 LM_DBG("core_hash= %u\n", hash_code);
00122
00123 for(p= L->next; p; p=p->next)
00124 {
00125 if((p->flag & pres->flag) && (p->event & pres->event))
00126 {
00127 if((p->pres_uri->len==pres->pres_uri->len) &&
00128 (strncmp(p->pres_uri->s, pres->pres_uri->s,pres->pres_uri->len)==0))
00129 {
00130 if(pres->id.s && pres->id.len)
00131 {
00132 if(!(pres->id.len== p->id.len &&
00133 strncmp(p->id.s, pres->id.s,pres->id.len)==0))
00134 continue;
00135 }
00136
00137 if(pres->watcher_uri)
00138 {
00139 if(p->watcher_uri->len==pres->watcher_uri->len &&
00140 (strncmp(p->watcher_uri->s, pres->watcher_uri->s,
00141 pres->watcher_uri->len )==0))
00142 {
00143 if(pres->remote_contact.s)
00144 if(pres->remote_contact.len== p->remote_contact.len &&
00145 strncmp(pres->remote_contact.s, p->remote_contact.s,
00146 p->remote_contact.len)== 0)
00147 break;
00148 }
00149 }
00150 else
00151 {
00152 if(pres->etag.s)
00153 {
00154 if(pres->etag.len== p->etag.len &&
00155 strncmp(p->etag.s, pres->etag.s,pres->etag.len)==0)
00156 break;
00157 }
00158 else
00159 {
00160 LM_DBG("no etag restriction\n");
00161 break;
00162 }
00163 }
00164 }
00165 }
00166 }
00167
00168 if(p)
00169 LM_DBG("found record\n");
00170 else
00171 LM_DBG("record not found\n");
00172
00173 return p;
00174 }
00175
00176 void update_htable(ua_pres_t* p, time_t desired_expires, int expires,
00177 str* etag, unsigned int hash_code, str* contact)
00178 {
00179 if(etag)
00180 {
00181 shm_free(p->etag.s);
00182 p->etag.s= (char*)shm_malloc(etag->len);
00183 memcpy(p->etag.s, etag->s, etag->len);
00184 p->etag.len= etag->len;
00185 }
00186
00187 p->expires= expires+ (int)time(NULL);
00188 p->desired_expires= desired_expires;
00189
00190 if(p->db_flag & NO_UPDATEDB_FLAG)
00191 p->db_flag= UPDATEDB_FLAG;
00192
00193 if(p->watcher_uri)
00194 p->cseq ++;
00195
00196 if(contact)
00197 {
00198 if(!(p->remote_contact.len== contact->len &&
00199 strncmp(p->remote_contact.s, contact->s, contact->len)==0))
00200 {
00201
00202 shm_free(p->remote_contact.s);
00203 p->remote_contact.s= (char*)shm_malloc(contact->len* sizeof(char));
00204 if(p->remote_contact.s== NULL)
00205 {
00206 LM_ERR("no more shared memory\n");
00207 return;
00208 }
00209 memcpy(p->remote_contact.s, contact->s, contact->len);
00210 p->remote_contact.len= contact->len;
00211 }
00212 }
00213 }
00214
00215 void insert_htable(ua_pres_t* presentity)
00216 {
00217 ua_pres_t* p= NULL;
00218 unsigned int hash_code;
00219
00220 hash_code= core_hash(presentity->pres_uri,presentity->watcher_uri,
00221 HASH_SIZE);
00222
00223 lock_get(&HashT->p_records[hash_code].lock);
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 p= HashT->p_records[hash_code].entity;
00234
00235 presentity->db_flag= INSERTDB_FLAG;
00236 presentity->next= p->next;
00237
00238 p->next= presentity;
00239
00240 lock_release(&HashT->p_records[hash_code].lock);
00241
00242 }
00243
00244 void delete_htable(ua_pres_t* presentity, unsigned int hash_code)
00245 {
00246 ua_pres_t* p= NULL, *q= NULL;
00247
00248 p= search_htable(presentity, hash_code);
00249 if(p== NULL)
00250 return;
00251
00252 q=HashT->p_records[hash_code].entity;
00253
00254 while(q->next!=p)
00255 q= q->next;
00256 q->next=p->next;
00257
00258 if(p->etag.s)
00259 shm_free(p->etag.s);
00260 else
00261 if(p->remote_contact.s)
00262 shm_free(p->remote_contact.s);
00263
00264 shm_free(p);
00265 p= NULL;
00266
00267 }
00268
00269 void destroy_htable(void)
00270 {
00271 ua_pres_t* p= NULL,*q= NULL;
00272 int i;
00273
00274 for(i=0; i<HASH_SIZE; i++)
00275 {
00276 lock_destroy(&HashT->p_records[i].lock);
00277 p=HashT->p_records[i].entity;
00278 while(p->next)
00279 {
00280 q=p->next;
00281 p->next=q->next;
00282 if(q->etag.s)
00283 shm_free(q->etag.s);
00284 else
00285 if(q->remote_contact.s)
00286 shm_free(q->remote_contact.s);
00287
00288 shm_free(q);
00289 q= NULL;
00290 }
00291 shm_free(p);
00292 }
00293 shm_free(HashT->p_records);
00294 shm_free(HashT);
00295
00296 return;
00297 }
00298
00299
00300 ua_pres_t* get_dialog(ua_pres_t* dialog, unsigned int hash_code)
00301 {
00302 ua_pres_t* p= NULL, *L;
00303 LM_DBG("core_hash= %u\n", hash_code);
00304
00305 L= HashT->p_records[hash_code].entity;
00306 for(p= L->next; p; p=p->next)
00307 {
00308
00309 if(p->flag& dialog->flag)
00310 {
00311 LM_DBG("pres_uri= %.*s\twatcher_uri=%.*s\n\t"
00312 "callid= %.*s\tto_tag= %.*s\tfrom_tag= %.*s\n",
00313 p->pres_uri->len, p->pres_uri->s, p->watcher_uri->len,
00314 p->watcher_uri->s,p->call_id.len, p->call_id.s,
00315 p->to_tag.len, p->to_tag.s, p->from_tag.len, p->from_tag.s);
00316
00317 LM_DBG("searched to_tag= %.*s\tfrom_tag= %.*s\n",
00318 p->to_tag.len, p->to_tag.s, p->from_tag.len, p->from_tag.s);
00319
00320 if((p->pres_uri->len== dialog->pres_uri->len) &&
00321 (strncmp(p->pres_uri->s, dialog->pres_uri->s,p->pres_uri->len)==0)&&
00322 (p->watcher_uri->len== dialog->watcher_uri->len) &&
00323 (strncmp(p->watcher_uri->s,dialog->watcher_uri->s,p->watcher_uri->len )==0)&&
00324 (strncmp(p->call_id.s, dialog->call_id.s, p->call_id.len)== 0) &&
00325 (strncmp(p->to_tag.s, dialog->to_tag.s, p->to_tag.len)== 0) &&
00326 (strncmp(p->from_tag.s, dialog->from_tag.s, p->from_tag.len)== 0) )
00327 {
00328 LM_DBG("FOUND dialog\n");
00329 break;
00330 }
00331 }
00332
00333 }
00334
00335 return p;
00336 }
00337
00338 int get_record_id(ua_pres_t* dialog, str** rec_id)
00339 {
00340 unsigned int hash_code;
00341 ua_pres_t* rec;
00342 str* id;
00343
00344 *rec_id= NULL;
00345
00346 hash_code= core_hash(dialog->pres_uri, dialog->watcher_uri, HASH_SIZE);
00347 lock_get(&HashT->p_records[hash_code].lock);
00348
00349 rec= get_dialog(dialog, hash_code);
00350 if(rec== NULL)
00351 {
00352 LM_DBG("Record not found\n");
00353 lock_release(&HashT->p_records[hash_code].lock);
00354 return 0;
00355 }
00356 id= (str*)pkg_malloc(sizeof(str));
00357 if(id== NULL)
00358 {
00359 LM_ERR("No more memory\n");
00360 lock_release(&HashT->p_records[hash_code].lock);
00361 return -1;
00362 }
00363 id->s= (char*)pkg_malloc(rec->id.len* sizeof(char));
00364 if(id->s== NULL)
00365 {
00366 LM_ERR("No more memory\n");
00367 pkg_free(id);
00368 lock_release(&HashT->p_records[hash_code].lock);
00369 return -1;
00370 }
00371 memcpy(id->s, rec->id.s, rec->id.len);
00372 id->len= rec->id.len;
00373
00374 lock_release(&HashT->p_records[hash_code].lock);
00375
00376 LM_DBG("rec did= %.*s\n", id->len, id->s);
00377
00378 *rec_id= id;
00379
00380 return 0;
00381 }
00382
00383 int is_dialog(ua_pres_t* dialog)
00384 {
00385 int ret_code= 0;
00386 unsigned int hash_code;
00387
00388 hash_code= core_hash(dialog->pres_uri, dialog->watcher_uri, HASH_SIZE);
00389 lock_get(&HashT->p_records[hash_code].lock);
00390
00391 if(get_dialog(dialog, hash_code)== NULL)
00392 ret_code= -1;
00393 else
00394 ret_code= 0;
00395 lock_release(&HashT->p_records[hash_code].lock);
00396
00397 return ret_code;
00398
00399 }
00400
00401 int update_contact(struct sip_msg* msg, char* str1, char* str2)
00402 {
00403 ua_pres_t* p, hentity;
00404 str contact;
00405 struct to_body *pto= NULL, TO, *pfrom = NULL;
00406 unsigned int hash_code;
00407
00408 if ( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00409 {
00410 LM_ERR("when parsing headers\n");
00411 return -1;
00412 }
00413
00414
00415 if( msg->callid==NULL || msg->callid->body.s==NULL)
00416 {
00417 LM_ERR("cannot parse callid header\n");
00418 return -1;
00419 }
00420
00421 if (!msg->from || !msg->from->body.s)
00422 {
00423 LM_ERR("cannot find 'from' header!\n");
00424 return -1;
00425 }
00426 if (msg->from->parsed == NULL)
00427 {
00428 if ( parse_from_header( msg )<0 )
00429 {
00430 LM_ERR("cannot parse From header\n");
00431 return -1;
00432 }
00433 }
00434
00435 pfrom = (struct to_body*)msg->from->parsed;
00436
00437 if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00438 {
00439 LM_ERR("no from tag value present\n");
00440 return -1;
00441 }
00442
00443 if( msg->to==NULL || msg->to->body.s==NULL)
00444 {
00445 LM_ERR("cannot parse TO header\n");
00446 return -1;
00447 }
00448
00449 if(msg->to->parsed != NULL)
00450 {
00451 pto = (struct to_body*)msg->to->parsed;
00452 LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
00453 }
00454 else
00455 {
00456 memset( &TO , 0, sizeof(TO) );
00457 parse_to(msg->to->body.s,msg->to->body.s +
00458 msg->to->body.len + 1, &TO);
00459 if(TO.uri.len <= 0)
00460 {
00461 LM_DBG("'To' header NOT parsed\n");
00462 return -1;
00463 }
00464 pto = &TO;
00465 }
00466 if( pto->tag_value.s ==NULL || pto->tag_value.len == 0)
00467 {
00468 LM_ERR("no from tag value present\n");
00469 return -1;
00470 }
00471 hentity.watcher_uri= &pto->uri;
00472 hentity.pres_uri= &pfrom->uri;
00473 hentity.call_id= msg->callid->body;
00474 hentity.to_tag= pto->tag_value;
00475 hentity.from_tag= pfrom->tag_value;
00476
00477 hash_code= core_hash(hentity.pres_uri,hentity.watcher_uri,
00478 HASH_SIZE);
00479
00480
00481 if(msg->contact== NULL || msg->contact->body.s== NULL)
00482 {
00483 LM_ERR("no contact header found in 200 OK reply");
00484 return -1;
00485 }
00486 contact= msg->contact->body;
00487
00488 lock_get(&HashT->p_records[hash_code].lock);
00489
00490 p= get_dialog(&hentity, hash_code);
00491 if(p== NULL)
00492 {
00493 lock_release(&HashT->p_records[hash_code].lock);
00494 LM_ERR("no record for the dialog found in hash table\n");
00495 return -1;
00496 }
00497
00498 shm_free(p->remote_contact.s);
00499
00500 if(!(p->remote_contact.len== contact.len &&
00501 strncmp(p->remote_contact.s, contact.s, contact.len)==0))
00502 {
00503
00504 shm_free(p->remote_contact.s);
00505 p->remote_contact.s= (char*)shm_malloc(contact.len* sizeof(char));
00506 if(p->remote_contact.s== NULL)
00507 {
00508 LM_ERR("no more shared memory\n");
00509 lock_release(&HashT->p_records[hash_code].lock);
00510 return -1;
00511 }
00512 memcpy(p->remote_contact.s, contact.s, contact.len);
00513 p->remote_contact.len= contact.len;
00514 }
00515
00516 lock_release(&HashT->p_records[hash_code].lock);
00517
00518 return 1;
00519
00520 }
00521