static void find_and_delete_dialog(ua_pres_t *dialog, int hash_code) { ua_pres_t *presentity; if (dbmode == PUA_DB_ONLY) { delete_dialog_puadb(dialog); } else { lock_get(&HashT->p_records[hash_code].lock); presentity= get_dialog(dialog, hash_code); if (presentity == NULL) { presentity = get_temporary_dialog(dialog, hash_code); if(presentity== NULL) { LM_ERR("no record found\n"); lock_release(&HashT->p_records[hash_code].lock); return; } } delete_htable(presentity, hash_code); lock_release(&HashT->p_records[hash_code].lock); } }
static void hashT_clean(unsigned int ticks,void *param) { int i; time_t now; ua_pres_t* p= NULL, *q= NULL; if (dbmode==PUA_DB_ONLY) { clean_puadb(update_period, min_expires ); return; } now = time(NULL); for(i= 0;i< HASH_SIZE; i++) { lock_get(&HashT->p_records[i].lock); p= HashT->p_records[i].entity->next; while(p) { print_ua_pres(p); if(p->expires- update_period < now ) { if((p->desired_expires> p->expires + min_expires) || (p->desired_expires== 0 )) { if(update_pua(p)< 0) { LM_ERR("while updating record\n"); lock_release(&HashT->p_records[i].lock); return; } p= p->next; continue; } if(p->expires < now - 10) { q= p->next; LM_DBG("Found expired: uri= %.*s\n", p->pres_uri->len, p->pres_uri->s); delete_htable(p, i); p= q; } else p= p->next; } else p= p->next; } lock_release(&HashT->p_records[i].lock); } }
int convert_temporary_dialog(ua_pres_t *dialog) { ua_pres_t *temp_dialog; unsigned int hash_code; hash_code= core_hash(dialog->pres_uri,dialog->watcher_uri, HASH_SIZE); lock_get(&HashT->p_records[hash_code].lock); temp_dialog = get_temporary_dialog(dialog, hash_code); if (temp_dialog) delete_htable(temp_dialog, hash_code); else return -1; insert_htable(dialog, hash_code); lock_release(&HashT->p_records[hash_code].lock); return 1; }
static void find_and_delete_record(ua_pres_t *dialog, int hash_code) { ua_pres_t *presentity; if (dbmode == PUA_DB_ONLY) { delete_record_puadb(dialog); } else { lock_get(&HashT->p_records[hash_code].lock); presentity = search_htable(dialog, hash_code); if (presentity == NULL) { LM_DBG("Record found in table and deleted\n"); lock_release(&HashT->p_records[hash_code].lock); return; } delete_htable(presentity, hash_code); lock_release(&HashT->p_records[hash_code].lock); } }
int send_subscribe(subs_info_t* subs) { ua_pres_t* presentity= NULL; str met= {"SUBSCRIBE", 9}; str* str_hdr= NULL; int ret= -1; unsigned int hash_code=0; ua_pres_t* hentity= NULL; int expires; int flag; int result; uac_req_t uac_r; db1_res_t *res=NULL; ua_pres_t dbpres; str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0}; dlg_t* td= NULL; memset(&dbpres, 0, sizeof(dbpres)); dbpres.pres_uri = &pres_uri; dbpres.watcher_uri = &watcher_uri; dbpres.extra_headers = &extra_headers; print_subs(subs); flag= subs->source_flag; if(subs->source_flag & XMPP_INITIAL_SUBS) subs->source_flag= XMPP_SUBSCRIBE; if(subs->expires< 0) expires= 3600; else expires= subs->expires; str_hdr= subs_build_hdr(subs->contact, expires, subs->event, subs->extra_headers); if(str_hdr== NULL || str_hdr->s== NULL) { LM_ERR("while building extra headers\n"); return -1; } if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction) { if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0) { LM_ERR("in start_transaction\n"); goto error; } } /* generation of hash and getting lock moved from here to further down */ if (dbmode==PUA_DB_ONLY) { presentity = get_dialog_puadb(subs->id, subs->pres_uri, &dbpres, &res); } else { ua_pres_t pres; memset(&pres, 0, sizeof(ua_pres_t)); pres.pres_uri = subs->pres_uri; pres.watcher_uri = subs->watcher_uri; pres.flag = subs->source_flag; pres.id = subs->id; pres.event = subs->event; if (subs->remote_target) pres.remote_contact = *subs->remote_target; hash_code=core_hash(subs->pres_uri, subs->watcher_uri, HASH_SIZE); lock_get(&HashT->p_records[hash_code].lock); presentity= search_htable(&pres, hash_code); } /* if flag == INSERT_TYPE insert no matter what the search result is */ if(subs->flag & INSERT_TYPE) { LM_DBG("A subscription request with insert type\n"); goto insert; } if(presentity== NULL ) { int size; insert: if (subs->expires == 0) { /* Don't create a new dialog when expires == 0 */ if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto done; } if(subs->flag & UPDATE_TYPE) { LM_DBG("request for a subscription with update type" " and no record found\n"); subs->flag= INSERT_TYPE; } hentity= subscribe_cbparam(subs, REQ_OTHER); if(hentity== NULL) { LM_ERR("while building callback" " param\n"); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } hentity->flag= flag; set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED, subs_cback_func, (void*)hentity); result= tmb.t_request_outside (&uac_r, /* Type of the message */ subs->remote_target?subs->remote_target:subs->pres_uri,/* Request-URI*/ subs->pres_uri, /* To */ subs->watcher_uri, /* From */ subs->outbound_proxy /* Outbound_proxy */ ); if(result< 0) { LM_ERR("while sending request with t_request\n"); if (uac_r.dialog != NULL) { uac_r.dialog->rem_target.s = 0; uac_r.dialog->dst_uri.s = 0; tmb.free_dlg(uac_r.dialog); uac_r.dialog = 0; } shm_free(hentity); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); /* Although this is an error must not return -1 as the calling function must continue processing. */ ret = 0; goto error; } /* Now create a temporary hash table entry. This is needed to deal with the race-hazard when NOTIFYs arrive before the 2xx response to the SUBSCRIBE. */ size = sizeof(ua_pres_t)+ 2 * sizeof(str) + ( subs->pres_uri->len + subs->watcher_uri->len + uac_r.dialog->id.loc_tag.len + uac_r.dialog->id.call_id.len + subs->id.len) * sizeof(char); presentity= (ua_pres_t*)shm_malloc(size); if(presentity== NULL) { LM_ERR("no more share memory\n"); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } memset(presentity, 0, size); size= sizeof(ua_pres_t); presentity->pres_uri = (str *) ((char *) presentity + size); size += sizeof(str); presentity->pres_uri->s= (char *) presentity + size; memcpy(presentity->pres_uri->s, subs->pres_uri->s, subs->pres_uri->len); presentity->pres_uri->len= subs->pres_uri->len; size+= subs->pres_uri->len; presentity->watcher_uri= (str *) ((char *) presentity + size); size += sizeof(str); presentity->watcher_uri->s= (char *) presentity + size; memcpy(presentity->watcher_uri->s, subs->watcher_uri->s, subs->watcher_uri->len); presentity->watcher_uri->len = subs->watcher_uri->len; size += subs->watcher_uri->len; presentity->call_id.s = (char *) presentity + size; memcpy(presentity->call_id.s, uac_r.dialog->id.call_id.s, uac_r.dialog->id.call_id.len); presentity->call_id.len = uac_r.dialog->id.call_id.len; size += uac_r.dialog->id.call_id.len; presentity->from_tag.s = (char *) presentity + size; memcpy(presentity->from_tag.s, uac_r.dialog->id.loc_tag.s, uac_r.dialog->id.loc_tag.len); presentity->from_tag.len= uac_r.dialog->id.loc_tag.len; size += uac_r.dialog->id.loc_tag.len; presentity->id.s = (char *) presentity+ size; memcpy(presentity->id.s, subs->id.s, subs->id.len); presentity->id.len = subs->id.len; size += subs->id.len; presentity->event = subs->event; presentity->flag = subs->source_flag; presentity->cseq = uac_r.dialog->loc_seq.value; /* Set the temporary record expiry for 2 * 64T1 seconds from now */ presentity->expires= (int)time(NULL) + 64; presentity->desired_expires= presentity->expires; if (dbmode==PUA_DB_ONLY) { insert_dialog_puadb(presentity); shm_free(presentity); } else { insert_htable(presentity, hash_code); lock_release(&HashT->p_records[hash_code].lock); } uac_r.dialog->rem_target.s = 0; uac_r.dialog->dst_uri.s = 0; tmb.free_dlg(uac_r.dialog); uac_r.dialog = 0; } else { if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE) { LM_INFO("attempting to re-SUBSCRIBE on internal (rls_update_subs()) update - skipping\n"); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto done; } if (presentity->to_tag.len == 0) { if (subs->expires > 0) LM_WARN("attempting to re-SUBSCRIBE to a temporary (non-established) dialog - skipping\n"); else { LM_WARN("attempting to un-SUBSCRIBE from a temporary (non-established) dialog - skipping and deleting dialog\n"); if (dbmode==PUA_DB_ONLY) delete_dialog_puadb(presentity); else delete_htable(presentity, hash_code); } if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto done; } td= pua_build_dlg_t(presentity); if(td== NULL) { LM_ERR("while building tm dlg_t structure"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } hentity= subs_cbparam_indlg(presentity, expires, REQ_OTHER); if(hentity== NULL) { LM_ERR("while building callback param\n"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); LM_DBG("event parameter: %d\n", hentity->event); set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED, subs_cback_func, (void*)hentity); result= tmb.t_request_within(&uac_r); if(result< 0) { shm_free(hentity); hentity= NULL; LM_ERR("while sending request with t_request\n"); goto error; } } done: if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction) { if (pua_dbf.end_transaction(pua_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } ret = 0; error: pua_free_tm_dlg(td); pkg_free(str_hdr); free_results_puadb(res); if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction) { if (pua_dbf.abort_transaction(pua_db) < 0) LM_ERR("in abort_transaction\n"); } return ret; }
void publ_cback_func(struct cell *t, int type, struct tmcb_params *ps) { struct hdr_field* hdr= NULL; struct sip_msg* msg= NULL; ua_pres_t* presentity= NULL; unsigned int lexpire= 0; str etag; unsigned int hash_index, local_index; unsigned long pres_id; if(ps->param == NULL) { LM_ERR("NULL parameter\n"); return; } msg= ps->rpl; if(msg == NULL) { LM_ERR("no reply message found\n"); return; } LM_DBG("cback param = %lu\n", (unsigned long)*ps->param); pres_id = (unsigned long)*ps->param; PUA_PARSE_PRES_ID(pres_id, hash_index, local_index); LM_DBG("hash_index= %u, local_index= %u\n", hash_index, local_index); if(!find_htable(hash_index, local_index)) { LM_ERR("No record found\n"); return; } if(msg== FAKED_REPLY) { LM_DBG("FAKED_REPLY\n"); goto done; } if( ps->code>= 300 ) { delete_htable(hash_index, local_index); goto done; } if( parse_headers(msg,HDR_EOH_F, 0)==-1 ) { LM_ERR("parsing headers\n"); return; } if(msg->expires== NULL || msg->expires->body.len<= 0) { LM_ERR("No Expires header found\n"); return; } if (!msg->expires->parsed && (parse_expires(msg->expires) < 0)) { LM_ERR("cannot parse Expires header\n"); return; } lexpire = ((exp_body_t*)msg->expires->parsed)->val; LM_DBG("lexpire= %u\n", lexpire); if(lexpire == 0) { delete_htable(hash_index, local_index); goto done; } hdr = get_header_by_static_name( msg, "SIP-ETag"); if( hdr==NULL ) /* must find SIP-Etag header field in 200 OK msg*/ { LM_ERR("no SIP-ETag header field found\n"); return; } etag= hdr->body; update_htable(hash_index, local_index, lexpire, &etag, 0); done: lock_get(&HashT->p_records[hash_index].lock); presentity = get_htable_safe(hash_index, local_index); if(!presentity) { LM_DBG("Record not found\n"); lock_release(&HashT->p_records[hash_index].lock); return; } if(presentity->ua_flag == REQ_OTHER) { run_pua_callbacks(presentity, msg); presentity->cb_param = NULL; } presentity->waiting_reply = 0; while(presentity->pending_publ) { publ_t* pending_publ = presentity->pending_publ; publ_info_t* publ = construct_pending_publ(presentity); if(publ == NULL) { LM_ERR("Failed to create publish record\n"); lock_release(&HashT->p_records[hash_index].lock); presentity->pending_publ = pending_publ->next; shm_free(pending_publ); continue; } LM_DBG("Found pending publish\n"); presentity->pending_publ = 0; presentity->waiting_reply = 1; send_publish_int(presentity, publ, get_event(presentity->event), presentity->hash_index); pkg_free(publ); presentity->pending_publ = pending_publ->next; shm_free(pending_publ); break; } lock_release(&HashT->p_records[hash_index].lock); }