void rtjson_free(void *ptr) { shm_free(ptr); }
void vq_free_call_id (queueID_t *call) { shm_free (call); }
subs_t* mem_copy_subs(subs_t* s, int mem_type) { int size; subs_t* dest; size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len + s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len + s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len + s->local_contact.len+ s->contact.len+ s->record_route.len + s->reason.len+ s->watcher_user.len+ s->watcher_domain.len + 1)*sizeof(char); if(mem_type & PKG_MEM_TYPE) dest= (subs_t*)pkg_malloc(size); else dest= (subs_t*)shm_malloc(size); if(dest== NULL) { ERR_MEM((mem_type==PKG_MEM_TYPE)?PKG_MEM_STR:SHARE_MEM); } memset(dest, 0, size); size= sizeof(subs_t); CONT_COPY(dest, dest->pres_uri, s->pres_uri) CONT_COPY(dest, dest->to_user, s->to_user) CONT_COPY(dest, dest->to_domain, s->to_domain) CONT_COPY(dest, dest->from_user, s->from_user) CONT_COPY(dest, dest->from_domain, s->from_domain) CONT_COPY(dest, dest->watcher_user, s->watcher_user) CONT_COPY(dest, dest->watcher_domain, s->watcher_domain) CONT_COPY(dest, dest->to_tag, s->to_tag) CONT_COPY(dest, dest->from_tag, s->from_tag) CONT_COPY(dest, dest->callid, s->callid) CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str) CONT_COPY(dest, dest->local_contact, s->local_contact) CONT_COPY(dest, dest->contact, s->contact) CONT_COPY(dest, dest->record_route, s->record_route) if(s->event_id.s) CONT_COPY(dest, dest->event_id, s->event_id) if(s->reason.s) CONT_COPY(dest, dest->reason, s->reason) dest->event= s->event; dest->local_cseq= s->local_cseq; dest->remote_cseq= s->remote_cseq; dest->status= s->status; dest->version= s->version; dest->send_on_cback= s->send_on_cback; dest->expires= s->expires; dest->db_flag= s->db_flag; return dest; error: if(dest) { if(mem_type & PKG_MEM_TYPE) pkg_free(dest); else shm_free(dest); } return NULL; }
/** * Deallocates memory used by a subscription. * \note Must be called with the lock got to avoid races * @param s - the ims_subscription to free */ void free_ims_subscription_data(ims_subscription *s) { int i, j, k; if (!s) return; /* lock_get(s->lock); - must be called with the lock got */ for (i = 0; i < s->service_profiles_cnt; i++) { for (j = 0; j < s->service_profiles[i].public_identities_cnt; j++) { if (s->service_profiles[i].public_identities[j].public_identity.s) shm_free(s->service_profiles[i].public_identities[j].public_identity.s); if (s->service_profiles[i].public_identities[j].wildcarded_psi.s) shm_free(s->service_profiles[i].public_identities[j].wildcarded_psi.s); } if (s->service_profiles[i].public_identities) shm_free(s->service_profiles[i].public_identities); for (j = 0; j < s->service_profiles[i].filter_criteria_cnt; j++) { if (s->service_profiles[i].filter_criteria[j].trigger_point) { for (k = 0; k < s->service_profiles[i].filter_criteria[j].trigger_point->spt_cnt; k++) { switch (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].type) { case IFC_REQUEST_URI: if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].request_uri.s) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].request_uri.s); break; case IFC_METHOD: if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].method.s) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].method.s); break; case IFC_SIP_HEADER: if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.header.s) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.header.s); if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.content.s) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].sip_header.content.s); break; case IFC_SESSION_CASE: break; case IFC_SESSION_DESC: if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.line.s) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.line.s); if (s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.content.s) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt[k].session_desc.content.s); break; } } if (s->service_profiles[i].filter_criteria[j].trigger_point->spt) shm_free(s->service_profiles[i].filter_criteria[j].trigger_point->spt); shm_free(s->service_profiles[i].filter_criteria[j].trigger_point); } if (s->service_profiles[i].filter_criteria[j].application_server.server_name.s) shm_free(s->service_profiles[i].filter_criteria[j].application_server.server_name.s); if (s->service_profiles[i].filter_criteria[j].application_server.service_info.s) shm_free(s->service_profiles[i].filter_criteria[j].application_server.service_info.s); if (s->service_profiles[i].filter_criteria[j].profile_part_indicator) shm_free(s->service_profiles[i].filter_criteria[j].profile_part_indicator); } if (s->service_profiles[i].filter_criteria) shm_free(s->service_profiles[i].filter_criteria); if (s->service_profiles[i].cn_service_auth) shm_free(s->service_profiles[i].cn_service_auth); if (s->service_profiles[i].shared_ifc_set) shm_free(s->service_profiles[i].shared_ifc_set); } if (s->service_profiles) shm_free(s->service_profiles); if (s->private_identity.s) shm_free(s->private_identity.s); // ul.unlock_subscription(s); #ifdef EXTRA_DEBUG LM_DBG("SUBSCRIPTION LOCK %p destroyed\n", s->lock); #endif lock_destroy(s->lock); lock_dealloc(s->lock); shm_free(s); }
int update_phtable(presentity_t* presentity, str pres_uri, str body) { char* sphere= NULL; unsigned int hash_code; pres_entry_t* p; int ret= 0; str* xcap_doc= NULL; /* get new sphere */ sphere= extract_sphere(body); if(sphere==NULL) { LM_DBG("no sphere defined in new body\n"); return 0; } /* search for record in hash table */ hash_code= core_case_hash(&pres_uri, NULL, phtable_size); lock_get(&pres_htable[hash_code].lock); p= search_phtable(&pres_uri, presentity->event->evp->type, hash_code); if(p== NULL) { lock_release(&pres_htable[hash_code].lock); goto done; } if(p->sphere) { if(strcmp(p->sphere, sphere)!= 0) { /* new sphere definition */ shm_free(p->sphere); } else { /* no change in sphere definition */ lock_release(&pres_htable[hash_code].lock); pkg_free(sphere); return 0; } } p->sphere= (char*)shm_malloc((strlen(sphere)+ 1)*sizeof(char)); if(p->sphere== NULL) { lock_release(&pres_htable[hash_code].lock); ret= -1; goto done; } strcpy(p->sphere, sphere); lock_release(&pres_htable[hash_code].lock); /* call for watchers status update */ if(presentity->event->get_rules_doc(&presentity->user, &presentity->domain, &xcap_doc)< 0) { LM_ERR("failed to retrieve xcap document\n"); ret= -1; goto done; } update_watchers_status(pres_uri, presentity->event, xcap_doc); done: if(xcap_doc) { if(xcap_doc->s) pkg_free(xcap_doc->s); pkg_free(xcap_doc); } if(sphere) pkg_free(sphere); return ret; }
static void xmlrpc_free(evi_reply_sock *sock) { /* nothing special here */ shm_free(sock); }
/* Function that inserts a new b2b_logic record - the lock remains taken */ b2bl_tuple_t* b2bl_insert_new(struct sip_msg* msg, unsigned int hash_index, b2b_scenario_t* scenario, str* args[], str* body, str* custom_hdrs, int local_index, str** b2bl_key_s, int db_flag) { b2bl_tuple_t *it, *prev_it; b2bl_tuple_t* tuple = NULL; str* b2bl_key; int i; static char buf[256]; int buf_len= 255; int size; str extra_headers={0, 0}; str local_contact= server_address; if(msg) { if(get_local_contact(msg->rcv.bind_address, &local_contact)< 0) { LM_ERR("Failed to get received address\n"); local_contact= server_address; } } size = sizeof(b2bl_tuple_t) + local_contact.len; tuple = (b2bl_tuple_t*)shm_malloc(size); if(tuple == NULL) { LM_ERR("No more shared memory\n"); goto error; } memset(tuple, 0, size); tuple->local_contact.s = (char*)(tuple + 1); memcpy(tuple->local_contact.s, local_contact.s, local_contact.len); tuple->local_contact.len = local_contact.len; tuple->scenario = scenario; if(msg) { if(b2b_extra_headers(msg, NULL, custom_hdrs, &extra_headers)< 0) { LM_ERR("Failed to create extra headers\n"); goto error; } if(extra_headers.s) { tuple->extra_headers = (str*)shm_malloc(sizeof(str) + extra_headers.len); if(tuple->extra_headers == NULL) { LM_ERR("No more shared memory\n"); goto error; } tuple->extra_headers->s = (char*)tuple->extra_headers + sizeof(str); memcpy(tuple->extra_headers->s, extra_headers.s, extra_headers.len); tuple->extra_headers->len = extra_headers.len; pkg_free(extra_headers.s); } } if(use_init_sdp || (scenario && scenario->use_init_sdp)) { if (!body && scenario->body.len) { body = &scenario->body; /* we also have to add the content type here */ tuple->extra_headers = (str *)shm_realloc(tuple->extra_headers, sizeof(str) + extra_headers.len + 14/* "Content-Type: " */ + 2/* "\r\n\" */ + scenario->body_type.len); if (!tuple->extra_headers) { LM_ERR("cannot add extra headers\n"); goto error; } /* restore initial data */ tuple->extra_headers->s = (char*)tuple->extra_headers + sizeof(str); tuple->extra_headers->len = extra_headers.len; memcpy(tuple->extra_headers->s + tuple->extra_headers->len, "Content-Type: ", 14); tuple->extra_headers->len += 14; memcpy(tuple->extra_headers->s + tuple->extra_headers->len, scenario->body_type.s, scenario->body_type.len); tuple->extra_headers->len += scenario->body_type.len; memcpy(tuple->extra_headers->s + tuple->extra_headers->len, "\r\n", 2); tuple->extra_headers->len += 2; } if (body) { /* alloc separate memory for sdp */ tuple->sdp.s = shm_malloc(body->len); if (!tuple->sdp.s) { LM_ERR("no more shm memory for sdp body\n"); goto error; } memcpy(tuple->sdp.s, body->s, body->len); tuple->sdp.len = body->len; } } /* copy the function parameters that customize the scenario */ memset(tuple->scenario_params, 0, MAX_SCENARIO_PARAMS* sizeof(str)); if(scenario && args) { for(i = 0; i< scenario->param_no; i++) { if(args[i]==NULL) { LM_DBG("Fewer parameters, expected [%d] received [%d]\n", scenario->param_no, i); break; } /* must print the value of the argument */ if(msg && b2bl_caller != CALLER_MODULE) { buf_len= 255; if(pv_printf(msg, (pv_elem_t*)args[i], buf, &buf_len)<0) { LM_ERR("cannot print the format\n"); goto error; } tuple->scenario_params[i].s = (char*)shm_malloc(buf_len); if(tuple->scenario_params[i].s == NULL) { LM_ERR("No more shared memory\n"); goto error; } memcpy(tuple->scenario_params[i].s, buf, buf_len); tuple->scenario_params[i].len = buf_len; LM_DBG("Printed parameter [%.*s]\n", buf_len, buf); } else { if(args[i]->s==NULL || args[i]->len==0) { LM_DBG("Fewer parameters, expected [%d] received [%d]\n", scenario->param_no, i); break; } tuple->scenario_params[i].s = (char*)shm_malloc(args[i]->len); if(tuple->scenario_params[i].s == NULL) { LM_ERR("No more shared memory\n"); goto error; } memcpy(tuple->scenario_params[i].s, args[i]->s, args[i]->len); tuple->scenario_params[i].len = args[i]->len; } } } tuple->scenario_state = B2B_NOTDEF_STATE; lock_get(&b2bl_htable[hash_index].lock); if(local_index>= 0) /* a local index specified */ { tuple->id = local_index; if(b2bl_htable[hash_index].first == NULL) { b2bl_htable[hash_index].first = tuple; tuple->prev = tuple->next = NULL; } else { prev_it = 0; /*insert it in the proper place */ for(it = b2bl_htable[hash_index].first; it && it->id<local_index; it=it->next) { prev_it = it; } if(!prev_it) { b2bl_htable[hash_index].first = tuple; tuple->prev = 0; tuple->next = it; it->prev = tuple; } else { tuple->prev = prev_it; prev_it->next = tuple; tuple->next = it; if(it) it->prev = tuple; } } } else { it = b2bl_htable[hash_index].first; if(it == NULL) { b2bl_htable[hash_index].first = tuple; tuple->prev = tuple->next = NULL; tuple->id = 0; } else { while(it) { prev_it = it; it = it->next; } prev_it->next = tuple; tuple->prev = prev_it; tuple->id = prev_it->id +1; } } LM_DBG("hash index [%d]:\n", hash_index); for(it = b2bl_htable[hash_index].first; it; it=it->next) { LM_DBG("id [%d]", it->id); } b2bl_key = b2bl_generate_key(hash_index, tuple->id); if(b2bl_key == NULL) { LM_ERR("failed to generate b2b logic key\n"); goto error; } tuple->key = b2bl_key; *b2bl_key_s = b2bl_key; tuple->db_flag = db_flag; LM_DBG("new tuple [%p]->[%.*s]\n", tuple, b2bl_key->len, b2bl_key->s); return tuple; error: if (tuple) { if (tuple->sdp.s) shm_free(tuple->sdp.s); shm_free(tuple); } lock_release(&b2bl_htable[hash_index].lock); return 0; }
int uac_reg_free_ht(void) { int i; reg_item_t *it = NULL; reg_item_t *it0 = NULL; if(_reg_htable_gc_lock != NULL) { lock_destroy(_reg_htable_gc_lock); shm_free((void*)_reg_htable_gc_lock); _reg_htable_gc_lock = NULL; } if(_reg_htable_gc!=NULL) { for(i=0; i<_reg_htable_gc->htsize; i++) { it = _reg_htable_gc->entries[i].byuuid; while(it) { it0 = it; it = it->next; shm_free(it0); } it = _reg_htable_gc->entries[i].byuser; while(it) { it0 = it; it = it->next; shm_free(it0->r); shm_free(it0); } } shm_free(_reg_htable_gc->entries); shm_free(_reg_htable_gc); _reg_htable_gc = NULL; } if(_reg_htable==NULL) { LM_DBG("no hash table\n"); return -1; } for(i=0; i<_reg_htable->htsize; i++) { lock_get(&_reg_htable->entries[i].lock); /* free entries */ it = _reg_htable->entries[i].byuuid; while(it) { it0 = it; it = it->next; shm_free(it0); } it = _reg_htable->entries[i].byuser; while(it) { it0 = it; it = it->next; shm_free(it0->r); shm_free(it0); } lock_destroy(&_reg_htable->entries[i].lock); } shm_free(_reg_htable->entries); shm_free(_reg_htable); _reg_htable = NULL; return 0; }
void uac_reg_tm_callback( struct cell *t, int type, struct tmcb_params *ps) { char *uuid; str suuid; reg_uac_t *ri = NULL; contact_t* c; int expires; struct sip_uri puri; struct hdr_field *hdr; HASHHEX response; str *new_auth_hdr = NULL; static struct authenticate_body auth; struct uac_credential cred; char b_ruri[MAX_URI_SIZE]; str s_ruri; #ifdef UAC_OLD_AUTH char b_turi[MAX_URI_SIZE]; str s_turi; #endif char b_hdrs[MAX_UACH_SIZE]; str s_hdrs; uac_req_t uac_r; str method = {"REGISTER", 8}; int ret; dlg_t tmdlg; if(ps->param==NULL || *ps->param==0) { LM_DBG("uuid not received\n"); return; } uuid = *((char**)ps->param); LM_DBG("completed with status %d [uuid: %s]\n", ps->code, uuid); suuid.s = uuid; suuid.len = strlen(suuid.s); ri = reg_ht_get_byuuid(&suuid); if(ri==NULL) { LM_DBG("no user with uuid %s\n", uuid); goto done; } if(ps->code == 200) { if (parse_headers(ps->rpl, HDR_EOH_F, 0) == -1) { LM_ERR("failed to parse headers\n"); goto error; } if (ps->rpl->contact==NULL) { LM_ERR("no Contact found\n"); goto error; } if (parse_contact(ps->rpl->contact) < 0) { LM_ERR("failed to parse Contact HF\n"); goto error; } if (((contact_body_t*)ps->rpl->contact->parsed)->star) { LM_DBG("* Contact found\n"); goto done; } if (contact_iterator(&c, ps->rpl, 0) < 0) goto done; while(c) { if(parse_uri(c->uri.s, c->uri.len, &puri)!=0) { LM_ERR("failed to parse c-uri\n"); goto error; } if(suuid.len==puri.user.len && (strncmp(puri.user.s, suuid.s, suuid.len)==0)) { /* calculate expires */ expires=0; if(c->expires==NULL || c->expires->body.len<=0) { if(ps->rpl->expires!=NULL && ps->rpl->expires->body.len>0) expires = atoi(ps->rpl->expires->body.s); } else { str2int(&c->expires->body, (unsigned int*)(&expires)); } ri->timer_expires = ri->timer_expires + expires; ri->flags |= UAC_REG_ONLINE; goto done; } if (contact_iterator(&c, ps->rpl, c) < 0) { LM_DBG("local contact not found\n"); goto done; } } } if(ps->code == 401 || ps->code == 407) { if(ri->flags & UAC_REG_AUTHSENT) { LM_ERR("authentication failed for <%.*s>\n", ri->l_uuid.len, ri->l_uuid.s); goto error; } hdr = get_autenticate_hdr(ps->rpl, ps->code); if (hdr==0) { LM_ERR("failed to extract authenticate hdr\n"); goto error; } LM_DBG("auth header body [%.*s]\n", hdr->body.len, hdr->body.s); if (parse_authenticate_body(&hdr->body, &auth)<0) { LM_ERR("failed to parse auth hdr body\n"); goto error; } if (ri->realm.len>0) { /* only check if realms match if it is non-empty */ if(auth.realm.len!=ri->realm.len || strncmp(auth.realm.s, ri->realm.s, ri->realm.len)!=0) { LM_ERR("realms do not match. requested realm: [%.*s]\n", auth.realm.len, auth.realm.s); goto error; } } cred.realm = auth.realm; cred.user = ri->auth_username; cred.passwd = ri->auth_password; cred.next = NULL; snprintf(b_ruri, MAX_URI_SIZE, "sip:%.*s", ri->r_domain.len, ri->r_domain.s); s_ruri.s = b_ruri; s_ruri.len = strlen(s_ruri.s); do_uac_auth(&method, &s_ruri, &cred, &auth, response); new_auth_hdr=build_authorization_hdr(ps->code, &s_ruri, &cred, &auth, response); if (new_auth_hdr==0) { LM_ERR("failed to build authorization hdr\n"); goto error; } #ifdef UAC_OLD_AUTH snprintf(b_turi, MAX_URI_SIZE, "sip:%.*s@%.*s", ri->r_username.len, ri->r_username.s, ri->r_domain.len, ri->r_domain.s); s_turi.s = b_turi; s_turi.len = strlen(s_turi.s); #endif snprintf(b_hdrs, MAX_UACH_SIZE, "Contact: <sip:%.*s@%.*s>\r\n" "Expires: %d\r\n" "%.*s", ri->l_uuid.len, ri->l_uuid.s, reg_contact_addr.len, reg_contact_addr.s, ri->expires, new_auth_hdr->len, new_auth_hdr->s); s_hdrs.s = b_hdrs; s_hdrs.len = strlen(s_hdrs.s); pkg_free(new_auth_hdr->s); memset(&uac_r, 0, sizeof(uac_r)); if(uac_reg_tmdlg(&tmdlg, ps->rpl)<0) { LM_ERR("failed to build tm dialog\n"); goto error; } tmdlg.rem_target = s_ruri; if(ri->auth_proxy.len) tmdlg.dst_uri = ri->auth_proxy; uac_r.method = &method; uac_r.headers = &s_hdrs; uac_r.dialog = &tmdlg; uac_r.cb_flags = TMCB_LOCAL_COMPLETED; /* Callback function */ uac_r.cb = uac_reg_tm_callback; /* Callback parameter */ uac_r.cbp = (void*)uuid; #ifdef UAC_OLD_AUTH ret = uac_tmb.t_request(&uac_r, /* UAC Req */ &s_ruri, /* Request-URI */ &s_turi, /* To */ &s_turi, /* From */ (ri->auth_proxy.len)?&ri->auth_proxy:NULL /* outbound uri */ ); #endif ret = uac_tmb.t_request_within(&uac_r); if(ret<0) { LM_ERR("failed to send request with authentication for [%.*s]", ri->l_uuid.len, ri->l_uuid.s); goto error; } ri->flags |= UAC_REG_AUTHSENT; return; } else { LM_ERR("got sip response %d while registering [%.*s]\n", ps->code, ri->l_uuid.len, ri->l_uuid.s); goto error; } error: if(reg_retry_interval) ri->timer_expires = time(NULL) + reg_retry_interval; else ri->flags |= UAC_REG_DISABLED; done: if(ri) ri->flags &= ~(UAC_REG_ONGOING|UAC_REG_AUTHSENT); shm_free(uuid); }
int update_pua(ua_pres_t* p) { str* str_hdr= NULL; int expires; int result; uac_req_t uac_r; int ret_code = 0; dlg_t* td = NULL; if(p->desired_expires== 0) expires= 3600; else expires= p->desired_expires- (int)time(NULL); if(p->watcher_uri == NULL || p->watcher_uri->len == 0) { str met= {"PUBLISH", 7}; ua_pres_t* cb_param; str_hdr = publ_build_hdr(expires, get_event(p->event), NULL, &p->etag, p->extra_headers, 0); if(str_hdr == NULL) { LM_ERR("while building extra_headers\n"); ret_code = -1; goto done; } LM_DBG("str_hdr:\n%.*s\n ", str_hdr->len, str_hdr->s); cb_param= build_uppubl_cbparam(p); if(cb_param== NULL) { LM_ERR("while constructing publ callback param\n"); ret_code = -1; goto done; } set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED, publ_cback_func, (void*)cb_param); result= tmb.t_request(&uac_r, p->pres_uri, /* Request-URI */ p->pres_uri, /* To */ p->pres_uri, /* From */ &outbound_proxy /* Outbound proxy*/ ); if(result< 0) { LM_ERR("in t_request function\n"); shm_free(cb_param); ret_code = -1; goto done; } } else { str met= {"SUBSCRIBE", 9}; ua_pres_t* cb_param= NULL; td= pua_build_dlg_t(p); if(td== NULL) { LM_ERR("while building tm dlg_t structure"); ret_code = -1; goto done; }; str_hdr= subs_build_hdr(&p->contact, expires,p->event,p->extra_headers); if(str_hdr== NULL || str_hdr->s== NULL) { if(p->event!=0) LM_ERR("while building extra headers\n"); ret_code = -1; goto done; } cb_param= subs_cbparam_indlg(p, expires, REQ_ME); if(cb_param== NULL) { LM_ERR("while constructing subs callback param\n"); ret_code = -1; goto done; } set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED, subs_cback_func, (void*)cb_param); result= tmb.t_request_within(&uac_r); if(result< 0) { LM_ERR("in t_request function\n"); shm_free(cb_param); ret_code = -1; goto done; } } done: if(td!=NULL) { if(td->route_set) free_rr(&td->route_set); pkg_free(td); td= NULL; } if(str_hdr) pkg_free(str_hdr); return ret_code; }
int uac_reg_init_ht(unsigned int sz) { int i; _reg_htable_gc_lock = (gen_lock_t*)shm_malloc(sizeof(gen_lock_t)); if(_reg_htable_gc_lock == NULL) { LM_ERR("no more shm for lock\n"); return -1; } if(lock_init(_reg_htable_gc_lock)==0) { LM_ERR("cannot init global lock\n"); shm_free((void*)_reg_htable_gc_lock); return -1; } _reg_htable_gc = (reg_ht_t*)shm_malloc(sizeof(reg_ht_t)); if(_reg_htable_gc==NULL) { LM_ERR("no more shm\n"); lock_destroy(_reg_htable_gc_lock); shm_free((void*)_reg_htable_gc_lock); return -1; } memset(_reg_htable_gc, 0, sizeof(reg_ht_t)); _reg_htable_gc->htsize = sz; _reg_htable_gc->entries = (reg_entry_t*)shm_malloc(_reg_htable_gc->htsize*sizeof(reg_entry_t)); if(_reg_htable_gc->entries==NULL) { LM_ERR("no more shm.\n"); shm_free(_reg_htable_gc); lock_destroy(_reg_htable_gc_lock); shm_free((void*)_reg_htable_gc_lock); return -1; } memset(_reg_htable_gc->entries, 0, _reg_htable_gc->htsize*sizeof(reg_entry_t)); _reg_htable = (reg_ht_t*)shm_malloc(sizeof(reg_ht_t)); if(_reg_htable==NULL) { LM_ERR("no more shm\n"); shm_free(_reg_htable_gc->entries); shm_free(_reg_htable_gc); lock_destroy(_reg_htable_gc_lock); shm_free((void*)_reg_htable_gc_lock); return -1; } memset(_reg_htable, 0, sizeof(reg_ht_t)); _reg_htable->htsize = sz; _reg_htable->entries = (reg_entry_t*)shm_malloc(_reg_htable->htsize*sizeof(reg_entry_t)); if(_reg_htable->entries==NULL) { LM_ERR("no more shm.\n"); shm_free(_reg_htable_gc->entries); shm_free(_reg_htable_gc); shm_free(_reg_htable); lock_destroy(_reg_htable_gc_lock); shm_free((void*)_reg_htable_gc_lock); return -1; } memset(_reg_htable->entries, 0, _reg_htable->htsize*sizeof(reg_entry_t)); for(i=0; i<_reg_htable->htsize; i++) { if(lock_init(&_reg_htable->entries[i].lock)==0) { LM_ERR("cannot initalize lock[%d] n", i); i--; while(i>=0) { lock_destroy(&_reg_htable->entries[i].lock); i--; } shm_free(_reg_htable->entries); shm_free(_reg_htable); shm_free(_reg_htable_gc->entries); shm_free(_reg_htable_gc); lock_destroy(_reg_htable_gc_lock); shm_free((void*)_reg_htable_gc_lock); return -1; } } return 0; }
static int db_restore(void) { ua_pres_t* p= NULL; db_key_t result_cols[19]; db1_res_t *res= NULL; db_row_t *row = NULL; db_val_t *row_vals= NULL; str pres_uri, pres_id; str etag, tuple_id; str watcher_uri, call_id; str to_tag, from_tag, remote_contact; str record_route, contact, extra_headers; int size= 0, i; int n_result_cols= 0; int puri_col,pid_col,expires_col,flag_col,etag_col, desired_expires_col; int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col; int event_col,contact_col,tuple_col,record_route_col, extra_headers_col; int version_col; unsigned int hash_code; if (dbmode==PUA_DB_ONLY) { LM_ERR( "db_restore shouldn't be called in PUA_DB_ONLY mode\n" ); return(-1); } result_cols[puri_col=n_result_cols++] = &str_pres_uri_col; result_cols[pid_col=n_result_cols++] = &str_pres_id_col; result_cols[expires_col=n_result_cols++]= &str_expires_col; result_cols[flag_col=n_result_cols++] = &str_flag_col; result_cols[etag_col=n_result_cols++] = &str_etag_col; result_cols[tuple_col=n_result_cols++] = &str_tuple_id_col; result_cols[watcher_col=n_result_cols++]= &str_watcher_uri_col; result_cols[callid_col=n_result_cols++] = &str_call_id_col; result_cols[totag_col=n_result_cols++] = &str_to_tag_col; result_cols[fromtag_col=n_result_cols++]= &str_from_tag_col; result_cols[cseq_col= n_result_cols++] = &str_cseq_col; result_cols[event_col= n_result_cols++] = &str_event_col; result_cols[record_route_col= n_result_cols++] = &str_record_route_col; result_cols[contact_col= n_result_cols++] = &str_contact_col; result_cols[remote_contact_col= n_result_cols++] = &str_remote_contact_col; result_cols[extra_headers_col= n_result_cols++] = &str_extra_headers_col; result_cols[desired_expires_col= n_result_cols++] = &str_desired_expires_col; result_cols[version_col= n_result_cols++] = &str_version_col; if(!pua_db) { LM_ERR("null database connection\n"); return -1; } if(pua_dbf.use_table(pua_db, &db_table)< 0) { LM_ERR("in use table\n"); return -1; } if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, 0, 0, 0, result_cols, 0, n_result_cols, 0, &res)< 0) { LM_ERR("while querrying table\n"); if(res) { pua_dbf.free_result(pua_db, res); res = NULL; } return -1; } if(res==NULL) return -1; if(res->n<=0) { LM_INFO("the query returned no result\n"); pua_dbf.free_result(pua_db, res); res = NULL; return 0; } do { LM_DBG("found %d db entries\n", res->n); for(i =0 ; i< res->n ; i++) { row = &res->rows[i]; row_vals = ROW_VALUES(row); pres_uri.s= (char*)row_vals[puri_col].val.string_val; pres_uri.len = strlen(pres_uri.s); LM_DBG("pres_uri= %.*s\n", pres_uri.len, pres_uri.s); memset(&etag, 0, sizeof(str)); memset(&tuple_id, 0, sizeof(str)); memset(&watcher_uri, 0, sizeof(str)); memset(&call_id, 0, sizeof(str)); memset(&to_tag, 0, sizeof(str)); memset(&from_tag, 0, sizeof(str)); memset(&record_route, 0, sizeof(str)); memset(&pres_id, 0, sizeof(str)); memset(&contact, 0, sizeof(str)); memset(&remote_contact, 0, sizeof(str)); memset(&extra_headers, 0, sizeof(str)); pres_id.s= (char*)row_vals[pid_col].val.string_val; if(pres_id.s) pres_id.len = strlen(pres_id.s); if(row_vals[etag_col].val.string_val) { etag.s= (char*)row_vals[etag_col].val.string_val; etag.len = strlen(etag.s); tuple_id.s= (char*)row_vals[tuple_col].val.string_val; tuple_id.len = strlen(tuple_id.s); } if(row_vals[watcher_col].val.string_val) { watcher_uri.s= (char*)row_vals[watcher_col].val.string_val; watcher_uri.len = strlen(watcher_uri.s); call_id.s= (char*)row_vals[callid_col].val.string_val; call_id.len = strlen(call_id.s); to_tag.s= (char*)row_vals[totag_col].val.string_val; to_tag.len = strlen(to_tag.s); from_tag.s= (char*)row_vals[fromtag_col].val.string_val; from_tag.len = strlen(from_tag.s); if(row_vals[record_route_col].val.string_val) { record_route.s= (char*)row_vals[record_route_col].val.string_val; record_route.len= strlen(record_route.s); } contact.s= (char*)row_vals[contact_col].val.string_val; contact.len = strlen(contact.s); remote_contact.s= (char*)row_vals[remote_contact_col].val.string_val; remote_contact.len = strlen(remote_contact.s); } extra_headers.s= (char*)row_vals[extra_headers_col].val.string_val; if(extra_headers.s) extra_headers.len= strlen(extra_headers.s); else extra_headers.len= 0; size= sizeof(ua_pres_t)+ sizeof(str)+ (pres_uri.len+ pres_id.len+ tuple_id.len)* sizeof(char); if(extra_headers.s) size+= sizeof(str)+ extra_headers.len* sizeof(char); if(watcher_uri.s) size+= sizeof(str)+ (watcher_uri.len+ call_id.len+ to_tag.len+ from_tag.len+ record_route.len+ contact.len)* sizeof(char); p= (ua_pres_t*)shm_malloc(size); if(p== NULL) { LM_ERR("no more share memmory"); goto error; } memset(p, 0, size); size= sizeof(ua_pres_t); p->pres_uri= (str*)((char*)p+ size); size+= sizeof(str); p->pres_uri->s= (char*)p + size; memcpy(p->pres_uri->s, pres_uri.s, pres_uri.len); p->pres_uri->len= pres_uri.len; size+= pres_uri.len; if(pres_id.s) { p->id.s= (char*)p + size; memcpy(p->id.s, pres_id.s, pres_id.len); p->id.len= pres_id.len; size+= pres_id.len; } if(tuple_id.s && tuple_id.len) { p->tuple_id.s= (char*)p + size; memcpy(p->tuple_id.s, tuple_id.s, tuple_id.len); p->tuple_id.len= tuple_id.len; size+= tuple_id.len; } if(watcher_uri.s && watcher_uri.len) { p->watcher_uri= (str*)((char*)p+ size); size+= sizeof(str); p->watcher_uri->s= (char*)p+ size; memcpy(p->watcher_uri->s, watcher_uri.s, watcher_uri.len); p->watcher_uri->len= watcher_uri.len; size+= watcher_uri.len; p->to_tag.s= (char*)p+ size; memcpy(p->to_tag.s, to_tag.s, to_tag.len); p->to_tag.len= to_tag.len; size+= to_tag.len; p->from_tag.s= (char*)p+ size; memcpy(p->from_tag.s, from_tag.s, from_tag.len); p->from_tag.len= from_tag.len; size+= from_tag.len; p->call_id.s= (char*)p + size; memcpy(p->call_id.s, call_id.s, call_id.len); p->call_id.len= call_id.len; size+= call_id.len; if(record_route.s && record_route.len) { p->record_route.s= (char*)p + size; memcpy(p->record_route.s, record_route.s, record_route.len); p->record_route.len= record_route.len; size+= record_route.len; } p->contact.s= (char*)p + size; memcpy(p->contact.s, contact.s, contact.len); p->contact.len= contact.len; size+= contact.len; p->cseq= row_vals[cseq_col].val.int_val; p->remote_contact.s= (char*)shm_malloc(remote_contact.len* sizeof(char)); if(p->remote_contact.s== NULL) { LM_ERR("No more shared memory\n"); goto error; } memcpy(p->remote_contact.s, remote_contact.s, remote_contact.len); p->remote_contact.len= remote_contact.len; p->version= row_vals[version_col].val.int_val; } if(extra_headers.s) { p->extra_headers= (str*)((char*)p+ size); size+= sizeof(str); p->extra_headers->s= (char*)p+ size; memcpy(p->extra_headers->s, extra_headers.s, extra_headers.len); p->extra_headers->len= extra_headers.len; size+= extra_headers.len; } LM_DBG("size= %d\n", size); p->event= row_vals[event_col].val.int_val; p->expires= row_vals[expires_col].val.int_val; p->desired_expires= row_vals[desired_expires_col].val.int_val; p->flag|= row_vals[flag_col].val.int_val; memset(&p->etag, 0, sizeof(str)); if(etag.s && etag.len) { /* alloc separately */ p->etag.s= (char*)shm_malloc(etag.len* sizeof(char)); if(p->etag.s== NULL) { LM_ERR("no more share memory\n"); goto error; } memcpy(p->etag.s, etag.s, etag.len); p->etag.len= etag.len; } print_ua_pres(p); hash_code= core_hash(p->pres_uri, p->watcher_uri, HASH_SIZE); lock_get(&HashT->p_records[hash_code].lock); insert_htable(p, hash_code); lock_release(&HashT->p_records[hash_code].lock); } } while((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1) && (RES_ROW_N(res)>0)); pua_dbf.free_result(pua_db, res); res = NULL; if(pua_dbf.delete(pua_db, 0, 0 , 0, 0) < 0) { LM_ERR("while deleting information from db\n"); goto error; } return 0; error: if(res) pua_dbf.free_result(pua_db, res); if(p) shm_free(p); return -1; }
static inline void write_log( struct cpl_cmd *cmd) { struct iovec wr_vec[5]; time_t now; char *time_ptr; int fd; int ret; /* build file name (cmd->s1 is the user name)*/ if (cmd->s1.len>MAX_LOG_FILE_NAME) cmd->s1.len = MAX_LOG_FILE_NAME; memcpy(file_ptr, cmd->s1.s, cmd->s1.len ); memcpy(file_ptr+cmd->s1.len,FILE_NAME_SUFIX,FILE_NAME_SUFIX_LEN); file_ptr[cmd->s1.len+FILE_NAME_SUFIX_LEN] = 0; /* get current date+time -> wr_vec[0] */ time( &now ); time_ptr = ctime( &now ); wr_vec[0].iov_base = time_ptr; wr_vec[0].iov_len = strlen( time_ptr ); /* ctime_r adds a \n at the end -> overwrite it with space */ time_ptr[ wr_vec[0].iov_len-1 ] = ' '; /* log name (cmd->s2) -> wr_vec[1] */ if (cmd->s2.s==0 || cmd->s2.len==0) { wr_vec[1].iov_base = DEFAULT_LOG_NAME; wr_vec[1].iov_len = DEFAULT_LOG_NAME_LEN; } else { wr_vec[1].iov_base = cmd->s2.s; wr_vec[1].iov_len = cmd->s2.len; } /* log separator -> wr_vec[2] */ wr_vec[2].iov_base = LOG_SEPARATOR; wr_vec[2].iov_len = LOG_SEPARATOR_LEN; /* log comment (cmd->s3) -> wr_vec[3] */ wr_vec[3].iov_base = cmd->s3.s; wr_vec[3].iov_len = cmd->s3.len; /* log terminator -> wr_vec[2] */ wr_vec[4].iov_base = LOG_TERMINATOR; wr_vec[4].iov_len = LOG_TERMINATOR_LEN; /* [create+]open the file */ fd = open( file, O_CREAT|O_APPEND|O_WRONLY, 0664); if (fd==-1) { LOG(L_ERR,"ERROR:cpl_c:write_log: cannot open file [%s] : %s\n", file, strerror(errno) ); return; } /* get the log */ DBG("DEBUG:cpl_c:write_log: logging into [%s]... \n",file); /* I'm really not interested in the return code for write ;-) */ while ( (ret=writev( fd, wr_vec, 5))==-1 ) { if (errno==EINTR) continue; LOG(L_ERR,"ERROR:cpl_c:write_log: writing to log file [%s] : %s\n", file, strerror(errno) ); } close (fd); shm_free( cmd->s1.s ); }
static inline void send_mail( struct cpl_cmd *cmd) { char *argv[5]; int pfd[2]; pid_t pid; int i; if (pipe(pfd) < 0) { LOG(L_ERR,"ERROR:cpl_c:send_mail: pipe failed: %s\n",strerror(errno)); return; } /* even if I haven't fork yet, I push the date on the pipe just to get * rid of one more malloc + copy */ if (cmd->s3.len && cmd->s3.s) { if ( (i=write( pfd[1], cmd->s3.s, cmd->s3.len ))!=cmd->s3.len ) { LOG(L_ERR,"ERROR:cpl_c:send_mail: write returned error %s\n", strerror(errno)); goto error; } } if ( (pid = fork()) < 0) { LOG(L_ERR,"ERROR:cpl_c:send_mail: fork failed: %s\n",strerror(errno)); goto error; } else if (pid==0) { /* child -> close all descriptors excepting pfd[0] */ for (i=3; i < MAX_FD; i++) if (i!=pfd[0]) close(i); if (pfd[0] != STDIN_FILENO) { dup2(pfd[0], STDIN_FILENO); close(pfd[0]); } /* set the argument vector*/ argv[0] = "mail"; argv[1] = "-s"; if (cmd->s2.s && cmd->s2.len) { /* put the subject in this format : <"$subject"\0> */ if ( (argv[2]=(char*)pkg_malloc(1+cmd->s2.len+1+1))==0) { LOG(L_ERR,"ERROR:cpl_c:send_mail: cannot get pkg memory\n"); goto child_exit; } argv[2][0] = '\"'; memcpy(argv[2]+1,cmd->s2.s,cmd->s2.len); argv[2][cmd->s2.len+1] = '\"'; argv[2][cmd->s2.len+2] = 0; } else { argv[2] = "\"[CPL notification]\""; } /* put the TO in <$to\0> format*/ if ( (argv[3]=(char*)pkg_malloc(cmd->s1.len+1))==0) { LOG(L_ERR,"ERROR:cpl_c:send_mail: cannot get pkg memory\n"); goto child_exit; } memcpy(argv[3],cmd->s1.s,cmd->s1.len); argv[3][cmd->s1.len] = 0; /* last element in vector mist be a null pointer */ argv[4] = (char*)0; /* just debug */ for(i=0;i<sizeof(argv)/sizeof(char*);i++) DBG(" argv[%d] = %s\n",i,argv[i]); /* once I copy localy all the data from shm mem -> free the shm */ shm_free( cmd->s1.s ); /* set an alarm -> sending the email shouldn't take more than 10 sec */ alarm(10); /* run the external mailer */ DBG("DEBUG:cpl_c:send_mail: new forked process created -> " "doing execv..\n"); execv("/usr/bin/mail",argv); /* if we got here means execv exit with error :-( */ LOG(L_ERR,"ERROR:cpl_c:send_mail: execv failed! (%s)\n", strerror(errno)); child_exit: _exit(127); } /* parent -> close both ends of pipe */ close(pfd[0]); close(pfd[1]); return; error: shm_free( cmd->s1.s ); close(pfd[0]); close(pfd[1]); return; }
int mod_init (void) { /********** * o allocate shared mem and init * o init configuration data * o init DB **********/ pmod_data = (mod_data *) shm_malloc (sizeof (mod_data)); if (!pmod_data) { LM_ERR ("Unable to allocate shared memory"); return -1; } memset (pmod_data, 0, sizeof (mod_data)); if (!init_cfg ()) { goto initerr; } if (!init_db ()) { goto initerr; } /********** * o bind to SL/TM/RR modules * o bind to RTPPROXY functions **********/ if (sl_load_api (pmod_data->psl)) { LM_ERR ("Unable to load SL module\n"); goto initerr; } if (load_tm_api (pmod_data->ptm)) { LM_ERR ("Unable to load TM module\n"); goto initerr; } if (load_rr_api (pmod_data->prr)) { LM_ERR ("Unable to load RR module\n"); goto initerr; } pmod_data->fn_rtp_answer = find_export ("rtpproxy_answer", 0, 0); if (!pmod_data->fn_rtp_answer) { LM_ERR ("Unable to load rtpproxy_answer\n"); goto initerr; } pmod_data->fn_rtp_offer = find_export ("rtpproxy_offer", 0, 0); if (!pmod_data->fn_rtp_offer) { LM_ERR ("Unable to load rtpproxy_offer\n"); goto initerr; } pmod_data->fn_rtp_stream_c = find_export ("rtpproxy_stream2uac", 2, 0); if (!pmod_data->fn_rtp_stream_c) { LM_ERR ("Unable to load rtpproxy_stream2uac\n"); goto initerr; } pmod_data->fn_rtp_stream_s = find_export ("rtpproxy_stream2uas", 2, 0); if (!pmod_data->fn_rtp_stream_s) { LM_ERR ("Unable to load rtpproxy_stream2uas\n"); goto initerr; } pmod_data->fn_rtp_destroy = find_export ("rtpproxy_destroy", 0, 0); if (!pmod_data->fn_rtp_destroy) { LM_ERR ("Unable to load rtpproxy_destroy\n"); goto initerr; } /********** * init MOH and call queue locks **********/ if (!mohq_lock_init (pmod_data->pmohq_lock)) { goto initerr; } if (!mohq_lock_init (pmod_data->pcall_lock)) { goto initerr; } return 0; /********** * o release shared mem * o exit with error **********/ initerr: if (pmod_data->mohq_cnt) { shm_free (pmod_data->pmohq_lst); } if (pmod_data->pcall_lock->plock) { mohq_lock_destroy (pmod_data->pcall_lock); } shm_free (pmod_data); pmod_data = NULL; return -1; }
int uac_reg_update(reg_uac_t *reg, time_t tn) { char *uuid; uac_req_t uac_r; str method = {"REGISTER", 8}; int ret; char b_ruri[MAX_URI_SIZE]; str s_ruri; char b_turi[MAX_URI_SIZE]; str s_turi; char b_hdrs[MAX_UACH_SIZE]; str s_hdrs; if(uac_tmb.t_request==NULL) return -1; if(reg->expires==0) return 1; if(reg->flags&UAC_REG_ONGOING) return 2; if(reg->flags&UAC_REG_DISABLED) return 4; if(reg->timer_expires > tn + reg_timer_interval + 3) return 3; reg->timer_expires = tn; reg->flags |= UAC_REG_ONGOING; reg->flags &= ~UAC_REG_ONLINE; uuid = (char*)shm_malloc(reg->l_uuid.len+1); if(uuid==NULL) { LM_ERR("no more shm\n"); return -1; } memcpy(uuid, reg->l_uuid.s, reg->l_uuid.len); uuid[reg->l_uuid.len] = '\0'; snprintf(b_ruri, MAX_URI_SIZE, "sip:%.*s", reg->r_domain.len, reg->r_domain.s); s_ruri.s = b_ruri; s_ruri.len = strlen(s_ruri.s); snprintf(b_turi, MAX_URI_SIZE, "sip:%.*s@%.*s", reg->r_username.len, reg->r_username.s, reg->r_domain.len, reg->r_domain.s); s_turi.s = b_turi; s_turi.len = strlen(s_turi.s); snprintf(b_hdrs, MAX_UACH_SIZE, "Contact: <sip:%.*s@%.*s>\r\n" "Expires: %d\r\n", reg->l_uuid.len, reg->l_uuid.s, reg_contact_addr.len, reg_contact_addr.s, reg->expires); s_hdrs.s = b_hdrs; s_hdrs.len = strlen(s_hdrs.s); memset(&uac_r, '\0', sizeof(uac_r)); uac_r.method = &method; uac_r.headers = &s_hdrs; uac_r.cb_flags = TMCB_LOCAL_COMPLETED; /* Callback function */ uac_r.cb = uac_reg_tm_callback; /* Callback parameter */ uac_r.cbp = (void*)uuid; ret = uac_tmb.t_request(&uac_r, /* UAC Req */ &s_ruri, /* Request-URI */ &s_turi, /* To */ &s_turi, /* From */ (reg->auth_proxy.len)?®->auth_proxy:NULL /* outbound uri */ ); if(ret<0) { LM_ERR("failed to send request for [%.*s]", reg->l_uuid.len, reg->l_uuid.s); shm_free(uuid); if (reg_retry_interval) reg->timer_expires = (tn ? tn : time(NULL)) + reg_retry_interval; else reg->flags |= UAC_REG_DISABLED; reg->flags &= ~UAC_REG_ONGOING; return -1; } return 0; }
/* * This is the parsing function * The socket grammar should be: * ip ':' port '/optional/path' ':' method */ static evi_reply_sock* xmlrpc_parse(str socket) { evi_reply_sock *sock = NULL; unsigned short port = 0; char *p = NULL; str host, path=str_init(NULL); struct hostent *hentity; int len; struct xmlrpc_sock_param *params; int http_buf_len=0; if (!socket.len || !socket.s) { LM_ERR("no socket specified\n"); return NULL; } if (!(params=shm_malloc(sizeof(struct xmlrpc_sock_param)))) { LM_ERR("no more pkg mem!\n"); return NULL; } memset(params, 0, sizeof(struct xmlrpc_sock_param)); /* extract host */ host.s = socket.s; p = memchr(socket.s, COLON_C, socket.len); if (!p || p == socket.s) { LM_ERR("port not specified <%.*s>\n", socket.len, socket.s); return NULL; } host.len = p - socket.s; /* used to resolve host */ *p = '\0'; /* skip colon */ socket.s += host.len + 1; socket.len -= host.len + 1; LM_DBG("host is %.*s - remains <%.*s>[%d]\n", host.len, host.s, socket.len, socket.s, socket.len); if (!socket.len || *socket.s == '\0') { LM_ERR("invalid port number\n"); return NULL; } p = memchr(socket.s, COLON_C, socket.len); if (!p || p == socket.s) { LM_ERR("method not specified <%.*s>\n", socket.len, socket.s); return NULL; } port = str2s(socket.s, p - socket.s, 0); if (port == 0) { /* most probably we've got path */ if ((path.s=(q_memchr(socket.s, SLASH_C, p-socket.s)))==NULL) { LM_ERR("malformed port: %.*s\n",(int)(p - socket.s), socket.s); return NULL; } else { port=str2s(socket.s, path.s-socket.s, 0); if (port == 0) { LM_ERR("malformed port: %.*s\n",(int)(p - socket.s), socket.s); return NULL; } path.len = p - path.s; socket.len -= ((path.s+path.len)-socket.s); socket.s = path.s+path.len; } /* will use this later for allocation */ http_buf_len=LENOF(XMLRPC_HTTP_METHOD) + path.len + LENOF(XMLRPC_HTTP_PROTO_HOST); } /* jump over ':' */ socket.len = socket.len - (p - socket.s + 1); socket.s = p + 1; LM_DBG("port is %hu - remains <%.*s>[%d]\n", port, socket.len, socket.s, socket.len); if (socket.len <= 0 || *socket.s == '\0') { LM_ERR("invalid method name\n"); return NULL; } len = sizeof(evi_reply_sock) + host.len + sizeof(struct xmlrpc_sock_param) + socket.len /* this is method */+ http_buf_len; sock = shm_malloc(len); if (!sock) { LM_ERR("no more memory for socket\n"); return NULL; } memset(sock, 0, len); /* only UDP has port */ sock->flags = EVI_PORT; sock->port = port; /* also build sockaddr */ hentity = resolvehost(host.s, 0); if (!hentity) { LM_ERR("cannot resolve host %s\n", host.s); goto error; } if(hostent2su(&sock->src_addr.udp_addr, hentity, 0, port)){ LM_ERR("failed to resolve %s\n", host.s); goto error; } sock->flags |= EVI_SOCKET; /* address */ sock->address.s = (char*)(sock+1); sock->address.len = host.len; memcpy(sock->address.s, host.s, host.len); sock->flags |= EVI_ADDRESS; /* copy parameters: path and method */ params = (struct xmlrpc_sock_param*)(sock->address.s + host.len); params->method.s = (char*)(params+1); memcpy(params->method.s, socket.s, socket.len); params->method.len = socket.len; if (http_buf_len) { /* build only once; not for every message */ params->first_line.s = (char*)(params->method.s+socket.len); memcpy(params->method.s, socket.s, socket.len); params->first_line.len = 0; memcpy(params->first_line.s, XMLRPC_HTTP_METHOD, LENOF(XMLRPC_HTTP_METHOD)); params->first_line.len = LENOF(XMLRPC_HTTP_METHOD); memcpy(params->first_line.s+params->first_line.len, path.s, path.len); params->first_line.len += path.len; memcpy(params->first_line.s+params->first_line.len, XMLRPC_HTTP_PROTO_HOST, LENOF(XMLRPC_HTTP_PROTO_HOST)); params->first_line.len += LENOF(XMLRPC_HTTP_PROTO_HOST); } else { params->first_line.s = XMLRPC_HTTP_CONST; params->first_line.len = LENOF(XMLRPC_HTTP_CONST); } sock->flags |= EVI_PARAMS; /* needs expire */ sock->flags |= EVI_EXPIRE|XMLRPC_FLAG; sock->params= params; return sock; error: if (sock) shm_free(sock); return NULL; }
void shm_free_x(void *ptr) { shm_free(ptr); }
void b2bl_delete(b2bl_tuple_t* tuple, unsigned int hash_index, int not_del_b2be) { b2bl_entity_id_t *e; int i; int index; b2bl_cb_params_t cb_params; LM_DBG("Delete record [%p]->[%.*s], hash_index=[%d], local_index=[%d]\n", tuple, tuple->key->len, tuple->key->s, hash_index, tuple->id); /* * razvanc: if the tuple is not actually deleted, we do not have to call * the DESTROY callback */ if(!not_del_b2be && tuple->cbf && tuple->cb_mask&B2B_DESTROY_CB) { memset(&cb_params, 0, sizeof(b2bl_cb_params_t)); cb_params.param = tuple->cb_param; cb_params.stat = NULL; cb_params.msg = NULL; /* setting it to 0 but it has no meaning in this callback type */ cb_params.entity = 0; tuple->cbf(&cb_params, B2B_DESTROY_CB); } if(!not_del_b2be) b2bl_db_delete(tuple); if(b2bl_htable[hash_index].first == tuple) { b2bl_htable[hash_index].first = tuple->next; if(tuple->next) tuple->next->prev = NULL; } else { if(tuple->prev) tuple->prev->next = tuple->next; if(tuple->next) tuple->next->prev = tuple->prev; } for (index = 0; index < MAX_B2BL_ENT; index++) { e = tuple->servers[index]; if (e) { if (e->key.s && e->key.len && !not_del_b2be) b2b_api.entity_delete(e->type, &e->key, e->dlginfo, 0); if(e->dlginfo) shm_free(e->dlginfo); shm_free(e); } e = tuple->clients[index]; if (e) { if (e->key.s && e->key.len && !not_del_b2be) b2b_api.entity_delete(e->type, &e->key, e->dlginfo, 0); if(e->dlginfo) shm_free(e->dlginfo); shm_free(e); } } /* clean up all entities in b2b_entities from db */ if(!not_del_b2be) b2b_api.entities_db_delete(*tuple->key); // if(tuple->bridge_entities[1] && tuple->bridge_entities[1]->key.s != NULL) // shm_free(tuple->bridge_entities[1]->key.s); for(i = 0; i< MAX_SCENARIO_PARAMS; i++) { if(tuple->scenario_params[i].s) shm_free(tuple->scenario_params[i].s); } if(tuple->key) shm_free(tuple->key); if(tuple->extra_headers) shm_free(tuple->extra_headers); if(tuple->b1_sdp.s) shm_free(tuple->b1_sdp.s); if (tuple->sdp.s && tuple->sdp.s != tuple->b1_sdp.s) shm_free(tuple->sdp.s); shm_free(tuple); }
void free_cpl_interpreter(struct cpl_interpreter *intr) { if (intr) { empty_location_set( &(intr->loc_set) ); if (intr->script.s) shm_free( intr->script.s); if (intr->user.s) shm_free(intr->user.s); if (intr->flags&CPL_RURI_DUPLICATED) shm_free(intr->ruri); if (intr->flags&CPL_TO_DUPLICATED) shm_free(intr->to); if (intr->flags&CPL_FROM_DUPLICATED) shm_free(intr->from); if (intr->flags&CPL_SUBJECT_DUPLICATED) shm_free(intr->subject); if (intr->flags&CPL_ORGANIZATION_DUPLICATED) shm_free(intr->organization); if (intr->flags&CPL_USERAGENT_DUPLICATED) shm_free(intr->user_agent); if (intr->flags&CPL_ACCEPTLANG_DUPLICATED) shm_free(intr->accept_language); if (intr->flags&CPL_PRIORITY_DUPLICATED) shm_free(intr->priority); shm_free(intr); } }
int mc_compress_cb(char** buf_p, void* param, int type, int* olen) { int rc; int len; int algo; int flags; int compress_len=0; int uncompress_len=0; int hdr_compress_len=0; str msg_start; char *buf=*buf_p; char *end=buf+strlen(buf); unsigned long temp; struct mc_comp_args *args=(struct mc_comp_args*)param; struct hdr_field *hf; struct hdr_field *mnd_hdrs=NULL; struct hdr_field *non_mnd_hdrs=NULL; struct hdr_field *mnd_hdrs_head=NULL; struct hdr_field *non_mnd_hdrs_head=NULL; mc_param_p wh_param; mc_whitelist_p hdr2compress_list; wh_param = args->wh_param; hdr2compress_list = args->hdr2compress_list; algo = args->algo; flags = args->flags; mc_parse_first_line(&msg_start, &buf); uncompress_len = msg_start.len; /* Parse the message until the body is found Build two lists one of mandatory headers and one of non mandatory headers */ while (1) { hf = pkg_malloc(sizeof(struct hdr_field)); if (hf == NULL) { LM_ERR("no more pkg mem\n"); goto free_mem_full; } memset(hf, 0, sizeof(struct hdr_field)); hf->type=HDR_ERROR_T; buf=get_hdr_field(buf, end, hf); if (hf->type == HDR_ERROR_T) { goto free_mem_full; } if (hf->type == HDR_EOH_T) { compress_len += strlen(buf); compress_len = compress_len > CRLF_LEN ? compress_len : 0; pkg_free(hf); break; } /*if Content-Length=0 then header must remain*/ if (hf->type == HDR_CONTENTLENGTH_T && hf->body.s[0] == '0') { goto set_mandatory; } if (mc_is_in_whitelist(hf, hdr2compress_list)) { if (!non_mnd_hdrs) { non_mnd_hdrs_head = non_mnd_hdrs = hf; } else { non_mnd_hdrs->next = hf; non_mnd_hdrs = non_mnd_hdrs->next; } /* in case will have a separate compressed header */ if ((flags&SEPARATE_COMP_FLG && flags&BODY_COMP_FLG && flags&HDR_COMP_FLG) || (flags&HDR_COMP_FLG && !(flags&BODY_COMP_FLG))) hdr_compress_len += hf->len; else compress_len += hf->len; } else { set_mandatory: if (!mnd_hdrs) { mnd_hdrs_head = mnd_hdrs = hf; } else { mnd_hdrs->next = hf; mnd_hdrs = mnd_hdrs->next; } uncompress_len += hf->len; } hf = 0; } str buf2compress={NULL, 0}; str hdr_buf2compress={NULL, 0}; /* Copy headers only if they exist and only if were asked*/ non_mnd_hdrs = non_mnd_hdrs_head; if (!non_mnd_hdrs || !(flags&HDR_COMP_FLG)) goto only_body; /* If body compression and header compression flags are set and they have to be together in the body */ if ((flags&BODY_COMP_FLG && flags&HDR_COMP_FLG && !(flags&SEPARATE_COMP_FLG)) || (flags&BODY_COMP_FLG && !(flags&HDR_COMP_FLG))){ if (wrap_realloc(&body_in, compress_len)) goto free_mem_full; buf2compress.s = body_in.s; buf2compress.len = 0; for (hf = non_mnd_hdrs; hf; hf = hf->next) { wrap_copy_and_update( &buf2compress.s, hf->name.s, hf->len, &buf2compress.len); } /* body compression and header compression but separately or only header compression */ } else if ((flags&BODY_COMP_FLG && flags&HDR_COMP_FLG && flags&SEPARATE_COMP_FLG) || (!(flags&BODY_COMP_FLG) && flags&HDR_COMP_FLG)) { if (wrap_realloc(&hdr_in, hdr_compress_len)) goto free_mem_full; hdr_buf2compress.s = hdr_in.s; for (hf = non_mnd_hdrs; hf; hf = hf->next) { wrap_copy_and_update( &hdr_buf2compress.s, hf->name.s, hf->len, &hdr_buf2compress.len); } } only_body: /* Copy the body of the message only if body compression is asked */ if (flags&BODY_COMP_FLG && compress_len) { if (!buf2compress.s) { if (wrap_realloc(&body_in, compress_len)) goto free_mem_full; buf2compress.s = body_in.s; } wrap_copy_and_update( &buf2compress.s, buf, strlen(buf), &buf2compress.len); } if (!buf2compress.s && !hdr_buf2compress.s) { LM_WARN("Nothing to compress. Specified headers not found\n"); goto free_mem_full; } /* Compress the message */ str bufcompressed={NULL, 0}; str hdr_bufcompressed={NULL, 0}; switch (algo) { case 0: /* deflate */ if (buf2compress.s) { bufcompressed.len = compressBound((unsigned long)buf2compress.len); if (wrap_realloc(&body_out, bufcompressed.len)) goto free_mem_full; bufcompressed.s = body_out.s; temp = (unsigned long)bufcompressed.len; rc = compress2((unsigned char*)bufcompressed.s, &temp, (unsigned char*)buf2compress.s, (unsigned long)buf2compress.len, mc_level); bufcompressed.len = (int)temp; if (check_zlib_rc(rc)) { LM_ERR("Body compression failed\n"); goto free_mem_full; } } if ((flags&HDR_COMP_FLG) && hdr_buf2compress.s) { hdr_bufcompressed.len = compressBound((unsigned long)hdr_buf2compress.len); if (wrap_realloc(&hdr_out, hdr_bufcompressed.len)) goto free_mem_full; hdr_bufcompressed.s = hdr_out.s; temp = (unsigned long)hdr_bufcompressed.len; rc = compress2((unsigned char*)hdr_bufcompressed.s, &temp, (unsigned char*)hdr_buf2compress.s, (unsigned long)hdr_buf2compress.len, mc_level); hdr_bufcompressed.len = temp; if (check_zlib_rc(rc)) { LM_ERR("Header compression failed\n"); goto free_mem_full; } } break; case 1: /* gzip */ if (buf2compress.s) { rc = gzip_compress( (unsigned char*)buf2compress.s, (unsigned long)buf2compress.len, &body_out, &temp, mc_level); if (check_zlib_rc(rc)) { LM_ERR("Body compression failed\n"); goto free_mem_full; } bufcompressed.s = body_out.s; bufcompressed.len = (int)temp; } if ((flags&HDR_COMP_FLG) && hdr_buf2compress.s) { rc = gzip_compress( (unsigned char*)hdr_buf2compress.s, (unsigned long)hdr_buf2compress.len, &hdr_out, &temp, mc_level); if (check_zlib_rc(rc)) { LM_ERR("Header compression failed\n"); goto free_mem_full; } hdr_bufcompressed.s = hdr_out.s; hdr_bufcompressed.len = temp; } break; default: LM_WARN("Invalind algo! no compression made\n"); goto free_mem_full; } str bufencoded={NULL, 0}; str hdr_bufencoded={NULL, 0}; if ((flags&B64_ENCODED_FLG) && bufcompressed.s) { bufencoded.len = calc_base64_encode_len(bufcompressed.len); if (wrap_realloc( &body_in, 2*CRLF_LEN + bufencoded.len)) goto free_mem_full; bufencoded.s = body_in.s; memcpy(bufencoded.s, CRLF, CRLF_LEN); base64encode((unsigned char*)(bufencoded.s + CRLF_LEN), (unsigned char*)bufcompressed.s, bufcompressed.len); } else if (bufcompressed.s) { if (wrap_realloc(&body_in, bufcompressed.len + 2*CRLF_LEN)) goto free_mem_full; /* !!! shift buf2compressed CRLF_LEN to the right !!! */ memcpy(body_in.s+CRLF_LEN, bufcompressed.s, bufcompressed.len); memcpy(body_in.s, CRLF, CRLF_LEN); bufencoded.len = bufcompressed.len; bufencoded.s = body_in.s; } if (hdr_bufcompressed.s) { hdr_bufencoded.len = calc_base64_encode_len(hdr_bufcompressed.len); if (wrap_realloc( &hdr_in, hdr_bufencoded.len + CRLF_LEN)) goto free_mem_full; hdr_bufencoded.s = hdr_in.s; base64encode((unsigned char*)hdr_bufencoded.s, (unsigned char*)hdr_bufcompressed.s, hdr_bufcompressed.len); wrap_copy_and_update(&hdr_bufencoded.s, CRLF, CRLF_LEN, &hdr_bufencoded.len); } /* Allocate the new buffer */ int alloc_size; str buf2send={NULL, 0}; alloc_size = msg_start.len + uncompress_len + CRLF_LEN/*the one before all headers*/; if (hdr_bufencoded.s) { alloc_size += COMP_HDRS_LEN + hdr_bufencoded.len; alloc_size += sizeof(HDRS_ENCODING) - 1; } /* if body compressed new content length and content encoding * plus if required more space for base64 in content encoding header*/ if (bufencoded.s) { alloc_size += CL_NAME_LEN + mc_ndigits(bufencoded.len) + CRLF_LEN; alloc_size += CE_NAME_LEN + CRLF_LEN; if (flags&B64_ENCODED_FLG) { alloc_size += ATTR_DELIM_LEN + (sizeof(BASE64_ALGO)-1); } } switch (algo) { case 0: /* deflate*/ if (bufencoded.s) alloc_size += DEFLATE_CE_LEN; if (hdr_bufencoded.s) alloc_size += sizeof(DEFLATE_ALGO) - 1; break; case 1: /* gzip */ if (bufencoded.s) alloc_size += GZIP_CE_LEN; if (hdr_bufencoded.s) alloc_size += sizeof(GZIP_ALGO) - 1; break; default: LM_ERR("compression algo not impelemented\n"); goto free_mem_full; } if (bufencoded.s) alloc_size += bufencoded.len + CRLF_LEN; else alloc_size += strlen(buf); if (wrap_realloc(&buf_out, alloc_size)) goto free_mem_full; buf2send.s = buf_out.s; /* Copy message start */ wrap_copy_and_update( &buf2send.s, msg_start.s, msg_start.len, &buf2send.len); /* Copy mandatory headers */ for (mnd_hdrs = mnd_hdrs_head; mnd_hdrs; mnd_hdrs = mnd_hdrs->next) { wrap_copy_and_update( &buf2send.s, mnd_hdrs->name.s, mnd_hdrs->len, &buf2send.len); } if ((flags&BODY_COMP_FLG) && bufencoded.s) { wrap_copy_and_update( &buf2send.s, CL_NAME, CL_NAME_LEN, &buf2send.len); wrap_copy_and_update( &buf2send.s, int2str(bufencoded.len, &len), mc_ndigits(bufencoded.len), &buf2send.len); wrap_copy_and_update( &buf2send.s, CRLF, CRLF_LEN, &buf2send.len); } if (hdr_bufencoded.s) { wrap_copy_and_update( &buf2send.s, COMP_HDRS, COMP_HDRS_LEN, &buf2send.len); wrap_copy_and_update( &buf2send.s, hdr_bufencoded.s, hdr_bufencoded.len, &buf2send.len); } switch (algo) { case 0: /* deflate */ if (hdr_bufencoded.s) { str hdr_name = str_init(HDRS_ENCODING), hdr_value = str_init(DEFLATE_ALGO); wrap_copy_and_update(&buf2send.s, hdr_name.s, hdr_name.len, &buf2send.len); if (flags & B64_ENCODED_FLG) { wrap_copy_and_update(&buf2send.s, BASE64_ALGO, sizeof(BASE64_ALGO)-1, &buf2send.len); wrap_copy_and_update(&buf2send.s, ATTR_DELIM, ATTR_DELIM_LEN, &buf2send.len); } wrap_copy_and_update(&buf2send.s, hdr_value.s, hdr_value.len, &buf2send.len); wrap_copy_and_update(&buf2send.s, CRLF, CRLF_LEN, &buf2send.len); } if (bufencoded.s) { wrap_copy_and_update(&buf2send.s, CE_NAME, CE_NAME_LEN, &buf2send.len); if (flags & B64_ENCODED_FLG) { wrap_copy_and_update(&buf2send.s, BASE64_ALGO, sizeof(BASE64_ALGO)-1, &buf2send.len); wrap_copy_and_update(&buf2send.s, ATTR_DELIM, ATTR_DELIM_LEN, &buf2send.len); } wrap_copy_and_update(&buf2send.s, DEFLATE_ALGO, sizeof(DEFLATE_ALGO)-1, &buf2send.len); wrap_copy_and_update(&buf2send.s, CRLF, CRLF_LEN, &buf2send.len); } break; case 1: /* gzip */ if (hdr_bufencoded.s) { str hdr_name = str_init(HDRS_ENCODING), hdr_value = str_init(GZIP_ALGO); if (flags & B64_ENCODED_FLG) { wrap_copy_and_update(&buf2send.s, BASE64_ALGO, sizeof(BASE64_ALGO)-1, &buf2send.len); wrap_copy_and_update(&buf2send.s, ATTR_DELIM, ATTR_DELIM_LEN, &buf2send.len); } wrap_copy_and_update(&buf2send.s, hdr_name.s, hdr_name.len, &buf2send.len); wrap_copy_and_update(&buf2send.s, hdr_value.s, hdr_value.len, &buf2send.len); wrap_copy_and_update(&buf2send.s, CRLF, CRLF_LEN, &buf2send.len); } if (bufencoded.s) { wrap_copy_and_update(&buf2send.s, CE_NAME, CE_NAME_LEN, &buf2send.len); if (flags & B64_ENCODED_FLG) { wrap_copy_and_update(&buf2send.s, BASE64_ALGO, sizeof(BASE64_ALGO)-1, &buf2send.len); wrap_copy_and_update(&buf2send.s, ATTR_DELIM, ATTR_DELIM_LEN, &buf2send.len); } wrap_copy_and_update(&buf2send.s, GZIP_ALGO, sizeof(GZIP_ALGO)-1, &buf2send.len); wrap_copy_and_update(&buf2send.s, CRLF, CRLF_LEN, &buf2send.len); } break; default: LM_ERR("compression algo not impelemented\n"); goto free_mem_full; } /* Copy message body */ if (bufencoded.s) { wrap_copy_and_update( &buf2send.s, bufencoded.s, bufencoded.len+CRLF_LEN, &buf2send.len); wrap_copy_and_update( &buf2send.s, CRLF, CRLF_LEN, &buf2send.len); } else { wrap_copy_and_update( &buf2send.s, buf, strlen(buf), &buf2send.len); } switch (type) { case TM_CB: shm_free(*buf_p); *buf_p = shm_malloc(buf2send.len+1); if (*buf_p == NULL) { LM_ERR("no more sh mem\n"); goto free_mem_full; } break; case PROCESSING_CB: *buf_p = pkg_malloc(buf2send.len+1); if (*buf_p == NULL) { LM_ERR("no more pkg mem\n"); goto free_mem_full; } break; default: LM_ERR("invalid type\n"); goto free_mem_full; } memcpy(*buf_p, buf2send.s, buf2send.len); (*buf_p)[buf2send.len] = '\0'; *olen = buf2send.len; free_hdr_list(&mnd_hdrs_head); free_hdr_list(&non_mnd_hdrs_head); if (wh_param && wh_param->type == WH_TYPE_PVS) free_whitelist(&hdr2compress_list); return 0; free_mem_full: free_hdr_list(&mnd_hdrs_head); free_hdr_list(&non_mnd_hdrs_head); if (wh_param && wh_param->type == WH_TYPE_PVS) free_whitelist(&hdr2compress_list); return -1; }
int cmd_erlang_info(struct sip_msg* msg, char *cn, char *rp, char *ar) { #define AVP_PRINTBUF_SIZE 1024 static char printbuf[AVP_PRINTBUF_SIZE]; int printbuf_len, bytessent; ei_x_buff argbuf; struct nodes_list* node; struct erlang_cmd *erl_cmd; erlang_pid erl_pid; str conname, regproc; int retcode = -1; if(msg==NULL) { LM_ERR("cmd_erlang_info: received null msg\n"); return -1; } if(fixup_get_svalue(msg, (gparam_p)cn, &conname)<0) { LM_ERR("cmd_erlang_info: cannot get the connection name\n"); return -1; } for(node=nodes_lst;node;node=node->next) { LM_DBG("cmd_erlang_info: matching %s with %.*s\n",node->name,conname.len,conname.s); if(strcmp(node->name, conname.s)==0) break; } if(node==0){ LM_ERR("cmd_erlang_info: no such connection %.*s\n",conname.len,conname.s); return -1; } if(fixup_get_svalue(msg, (gparam_p)rp, ®proc)<0) { LM_ERR("cmd_erlang_info: cannot get the regproc name\n"); return -1; } printbuf_len = AVP_PRINTBUF_SIZE-1; if(pv_printf(msg, (pv_elem_p)ar, printbuf, &printbuf_len)<0 || printbuf_len<=0) { LM_ERR("cmd_erlang_info: cannot expand erlang message body\n"); return -1; } erl_cmd=shm_malloc(sizeof(struct erlang_cmd)); if(!erl_cmd) { LM_ERR("no shm"); return -1; } memset(erl_cmd,0,sizeof(struct erlang_cmd)); erl_cmd->erlbuf=shm_malloc(AVP_PRINTBUF_SIZE); if (!erl_cmd->erlbuf) { LM_ERR("no shm memory\n\n"); goto error; } if(lock_init(&(erl_cmd->lock))==NULL) { LM_ERR("cannot init the lock\n"); goto error; } erl_cmd->reg_name=shm_strdup(®proc); if (!erl_cmd->reg_name) { LM_ERR("no shm memory\n\n"); goto error; } LM_DBG("cmd_erlang_info: %.*s %.*s %.*s\n",conname.len,conname.s, regproc.len,regproc.s, printbuf_len,printbuf); erl_cmd->cmd=ERLANG_INFO; erl_cmd->node=node; argbuf.buff=erl_cmd->erlbuf; argbuf.buffsz=AVP_PRINTBUF_SIZE-1; argbuf.index=0; ei_x_encode_version(&argbuf); //User passed term will be sedond element of tuple, first is our erlang pid ei_x_encode_tuple_header(&argbuf, 2); // we are hacking erlang pid so we can have worker system pid here memcpy(&erl_pid,ei_self(&(node->ec)),sizeof(erlang_pid)); erl_pid.num=getpid(); ei_x_encode_pid(&argbuf, &erl_pid); //so much for pid, now encode term if(ei_x_format_wo_ver(&argbuf, printbuf)!=0) { LM_ERR("cannot fromat erlang binary from arg string\n"); goto error; } // ei_x_encode_atom(&argbuf,"user"); erl_cmd->erlbuf_len=argbuf.index; lock_get(&(erl_cmd->lock)); bytessent=write(pipe_fds[1], &erl_cmd, sizeof(erl_cmd)); LM_DBG("cmd_erlang_info: locked, sent %d %d %s %d %p %p, waiting for release\n",bytessent, erl_cmd->cmd,erl_cmd->reg_name,erl_cmd->erlbuf_len,erl_cmd->erlbuf, erl_cmd); lock_get(&(erl_cmd->lock)); LM_DBG("after lock\n"); if (erl_cmd->retcode <0) { retcode=erl_cmd->retcode; LM_DBG("cmd_erlang_info: failed %d\n",retcode); goto error; } retcode=1; error: if(erl_cmd) { if(erl_cmd->erlbuf) shm_free(erl_cmd->erlbuf); if(erl_cmd->reg_name) shm_free(erl_cmd->reg_name); shm_free(erl_cmd); } return retcode; }
/*! * \brief Create and initialize new record structure * \param _dom domain name * \param _aor address of record * \param _r pointer to the new record * \return 0 on success, negative on failure */ int new_impurecord(str* _dom, str* public_identity, str* private_identity, int reg_state, int barring, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, impurecord_t** _r) { *_r = (impurecord_t*) shm_malloc(sizeof (impurecord_t)); if (*_r == 0) { LM_ERR("no more shared memory\n"); return -1; } memset(*_r, 0, sizeof (impurecord_t)); //setup callback list (*_r)->cbs = (struct ulcb_head_list*) shm_malloc( sizeof (struct ulcb_head_list)); if ((*_r)->cbs == 0) { LM_CRIT("no more shared mem\n"); shm_free(*_r); goto error; } (*_r)->cbs->first = 0; (*_r)->cbs->reg_types = 0; (*_r)->public_identity.s = (char*) shm_malloc(public_identity->len); if ((*_r)->public_identity.s == 0) { LM_ERR("no more shared memory\n"); shm_free(*_r); goto error; } memcpy((*_r)->public_identity.s, public_identity->s, public_identity->len); (*_r)->public_identity.len = public_identity->len; (*_r)->private_identity.s = (char*) shm_malloc(private_identity->len); if ((*_r)->private_identity.s == 0) { LM_ERR("no more shared memory\n"); shm_free(*_r); goto error; } memcpy((*_r)->private_identity.s, private_identity->s, private_identity->len); (*_r)->private_identity.len = private_identity->len; (*_r)->domain = _dom; (*_r)->aorhash = core_hash(public_identity, 0, 0); (*_r)->reg_state = reg_state; if (barring >= 0) { //just in case we call this with no barring -1 will ignore (*_r)->barring = barring; } (*_r)->send_sar_on_delete = 1; /*defaults to 1 */ if (ccf1 && ccf1->len > 0) STR_SHM_DUP((*_r)->ccf1, *ccf1, "CCF1"); if (ccf2 && ccf2->len > 0) STR_SHM_DUP((*_r)->ccf2, *ccf2, "CCF2"); if (ecf1 && ecf1->len > 0) STR_SHM_DUP((*_r)->ecf1, *ecf1, "ECF1"); if (ecf2 && ecf2->len > 0) STR_SHM_DUP((*_r)->ecf2, *ecf2, "ECF2"); /*assign ims subscription profile*/ if (s && *s) { ref_subscription_unsafe(*s); (*_r)->s = *s; } return 0; out_of_memory: LM_ERR("no more shared memory\n"); *_r = 0; return -3; error: LM_ERR("Failed to create new impurecord...\n"); *_r = 0; return -2; }
struct bl_head *create_bl_head(int owner, int flags, struct bl_rule *head, struct bl_rule *tail, str *name) { unsigned int i; i = used_heads; if (i==max_heads) { LM_ERR("too many lists\n"); return NULL; } if (get_bl_head_by_name(name)!=NULL) { LM_CRIT("duplicated name!\n"); return NULL; } if ( flags&BL_READONLY_LIST && flags&BL_DO_EXPIRE){ LM_CRIT("RO lists cannot accept EXPIRES!\n"); return NULL; } /* copy list name */ if (no_shm) blst_heads[i].name.s = (char*)pkg_malloc(name->len + 1); else blst_heads[i].name.s = (char*)shm_malloc(name->len + 1); if (blst_heads[i].name.s==NULL) { LM_ERR("no more pkg memory!\n"); return NULL; } memcpy( blst_heads[i].name.s, name->s, name->len); blst_heads[i].name.s[name->len] = '\0'; blst_heads[i].name.len = name->len; /* build lock? */ if (!no_shm && !(flags&BL_READONLY_LIST)) { if ( (blst_heads[i].lock=lock_alloc())==NULL ) { LM_ERR("failed to create lock!\n"); shm_free(blst_heads[i].name.s); return NULL; } if ( lock_init(blst_heads[i].lock)==NULL ) { LM_ERR("failed to init lock!\n"); shm_free(blst_heads[i].name.s); lock_dealloc(blst_heads[i].lock); return NULL; } } used_heads++; blst_heads[i].owner = owner; blst_heads[i].flags = flags; blst_heads[i].first = head; blst_heads[i].last = tail; if (flags&BL_BY_DEFAULT) bl_default_marker |= (1<<i); return blst_heads + i; }
void timer_free(struct timer_ln* t) { shm_free(t); }
str* client_new(client_info_t* ci,b2b_notify_t b2b_cback, b2b_add_dlginfo_t add_dlginfo, str* param) { int result; b2b_dlg_t* dlg; unsigned int hash_index; str* callid = NULL; int size; str ehdr = {0, 0}; str* b2b_key_shm = NULL; dlg_t td; str from_tag; str random_info = {0, 0}; if(ci == NULL || b2b_cback == NULL || param== NULL) { LM_ERR("Wrong parameters.\n"); return NULL; } if(param && param->len > B2BL_MAX_KEY_LEN) { LM_ERR("parameter too long, received [%d], maximum [%d]\n", param->len, B2BL_MAX_KEY_LEN); return 0; } hash_index = core_hash(&ci->from_uri, &ci->to_uri, client_hsize); if(ci->from_tag) from_tag = *ci->from_tag; else generate_tag(&from_tag, &ci->from_uri, ci->extra_headers); /* create a dummy b2b dialog structure to be inserted in the hash table*/ size = sizeof(b2b_dlg_t) + ci->to_uri.len + ci->from_uri.len + ci->from_dname.len + ci->to_dname.len + from_tag.len + ci->local_contact.len + B2B_MAX_KEY_SIZE + B2BL_MAX_KEY_LEN; /* create record in hash table */ dlg = (b2b_dlg_t*)shm_malloc(size); if(dlg == NULL) { LM_ERR("No more shared memory\n"); return 0; } memset(dlg, 0, size); size = sizeof(b2b_dlg_t); CONT_COPY(dlg, dlg->from_uri, ci->from_uri); CONT_COPY(dlg, dlg->to_uri, ci->to_uri); if(ci->to_dname.s) CONT_COPY(dlg, dlg->to_dname, ci->to_dname); if(ci->from_dname.s) CONT_COPY(dlg, dlg->from_dname, ci->from_dname); CONT_COPY(dlg, dlg->tag[CALLER_LEG], from_tag); CONT_COPY(dlg, dlg->contact[CALLER_LEG], ci->local_contact); if(param && param->s) { dlg->param.s = (char*)dlg + size; memcpy(dlg->param.s, param->s, param->len); dlg->param.len = param->len; size+= B2BL_MAX_KEY_LEN; } dlg->b2b_cback = b2b_cback; dlg->add_dlginfo = add_dlginfo; if(parse_method(ci->method.s, ci->method.s+ci->method.len, &dlg->last_method)< 0) { LM_ERR("wrong method %.*s\n", ci->method.len, ci->method.s); shm_free(dlg); goto error; } dlg->state = B2B_NEW; dlg->cseq[CALLER_LEG] =(ci->cseq?ci->cseq:1); dlg->send_sock = ci->send_sock; /* if the callid should be the same in more instances running at the same time (replication)*/ if(!replication_mode) { srand(get_uticks()); random_info.s = int2str(rand(), &random_info.len); } dlg->send_sock = ci->send_sock; dlg->id = core_hash(&from_tag, random_info.s?&random_info:0, HASH_SIZE); /* callid must have the special format */ dlg->db_flag = NO_UPDATEDB_FLAG; callid = b2b_htable_insert(client_htable, dlg, hash_index, B2B_CLIENT, 0); if(callid == NULL) { LM_ERR("Inserting new record in hash table failed\n"); shm_free(dlg); goto error; } if(b2breq_complete_ehdr(ci->extra_headers, &ehdr, ci->body, &ci->local_contact)< 0) { LM_ERR("Failed to complete extra headers\n"); goto error; } /* copy the key in shared memory to transmit it as a parameter to the tm callback */ b2b_key_shm = b2b_key_copy_shm(callid); if(b2b_key_shm== NULL) { LM_ERR("no more shared memory\n"); goto error; } CONT_COPY(dlg, dlg->callid, (*callid)); /* create the tm dialog structure with the a costum callid */ memset(&td, 0, sizeof(dlg_t)); td.loc_seq.value = dlg->cseq[CALLER_LEG]; dlg->last_invite_cseq = dlg->cseq[CALLER_LEG]; td.loc_seq.is_set = 1; td.id.call_id = *callid; td.id.loc_tag = from_tag; td.id.rem_tag.s = 0; td.id.rem_tag.len = 0; td.rem_uri = ci->to_uri; if(ci->req_uri.s) td.rem_target = ci->req_uri; else td.rem_target = ci->to_uri; if(td.rem_target.s[0] == '<') { td.rem_target.s++; td.rem_target.len-=2; } td.rem_dname = ci->to_dname; td.loc_uri = ci->from_uri; td.loc_dname = ci->from_dname; td.state= DLG_CONFIRMED; td.T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ; td.send_sock = ci->send_sock; if(ci->dst_uri.len) td.obp = ci->dst_uri; td.avps = ci->avps; tmb.setlocalTholder(&dlg->uac_tran); /* send request */ result= tmb.t_request_within (&ci->method, /* method*/ &ehdr, /* extra headers*/ ci->body, /* body*/ &td, /* dialog structure*/ b2b_client_tm_cback, /* callback function*/ b2b_key_shm, shm_free_param); /* function to release the parameter*/ if(td.route_set) pkg_free(td.route_set); if(result< 0) { LM_ERR("while sending request with t_request\n"); pkg_free(callid); shm_free(b2b_key_shm); return NULL; } tmb.setlocalTholder(NULL); LM_DBG("new client entity [%p] callid=[%.*s] tag=[%.*s] param=[%.*s]" " last method=[%d] dlg->uac_tran=[%p]\n", dlg, callid->len, callid->s, dlg->tag[CALLER_LEG].len, dlg->tag[CALLER_LEG].s, dlg->param.len, dlg->param.s, dlg->last_method, dlg->uac_tran); return callid; error: if(callid) pkg_free(callid); return NULL; }
/* * arguments: b2bl_key, new_dest, entity (1 - client) * */ static struct mi_root* mi_b2b_bridge(struct mi_root* cmd, void* param) { struct mi_node* node= NULL; str key; b2bl_tuple_t* tuple; str new_dest; str prov_media; unsigned int entity_no = 0; b2bl_entity_id_t* entity, *old_entity, *bridging_entity, *prov_entity = 0; struct sip_uri uri; str meth_inv = {INVITE, INVITE_LEN}; str meth_bye = {BYE, BYE_LEN}; unsigned int hash_index, local_index; str ok= str_init("ok"); b2b_req_data_t req_data; b2b_rpl_data_t rpl_data; node = cmd->node.kids; if(node == NULL) return 0; /* b2bl_key */ key = node->value; if(key.s == NULL || key.len== 0) { LM_ERR("Wrong b2b_logic key parameter\n"); return init_mi_tree(404, "Empty b2bl key", 14); } /* new destination- must be a valid SIP URI */ node = node->next; if(node == NULL) return 0; new_dest = node->value; if(new_dest.s == NULL || new_dest.len == 0) { LM_ERR("Empty new dest parameter\n"); return init_mi_tree(404, "Empty parameter", 15); } if(parse_uri(new_dest.s, new_dest.len, &uri)< 0) { LM_ERR("Bad argument. Not a valid uri [%.*s]\n", new_dest.len, new_dest.s); return init_mi_tree(404, "Bad parameter", 13); } /* the last parameter is optional, if present and 1 - > * means that destination from the current call must be * bridged to the new destination */ node = node->next; if(node) { if (node->value.len==1) { if(strncmp(node->value.s, "0", 1)==0) entity_no = 0; else if(strncmp(node->value.s, "1", 1)==0) entity_no = 1; else return init_mi_tree(404, "Invalid entity no parameter", 27); } else { return init_mi_tree(404, "Invalid entity no parameter", 27); } node = node->next; if (node) { /* parse new uri */ prov_media = node->value; if(parse_uri(node->value.s, node->value.len, &uri)< 0) { LM_ERR("Bad argument. Not a valid provisional media uri [%.*s]\n", new_dest.len, new_dest.s); return init_mi_tree(404, "Bad parameter", 13); } prov_entity = b2bl_create_new_entity(B2B_CLIENT, 0, &prov_media, 0, 0, 0, 0, 0); if (!prov_entity) { LM_ERR("Failed to create new b2b entity\n"); goto free; } if (node->next) return init_mi_tree(404, MI_SSTR(MI_MISSING_PARM)); } } if(b2bl_parse_key(&key, &hash_index, &local_index) < 0) { LM_ERR("Failed to parse key '%.*s'\n", key.len, key.s); goto free; } entity = b2bl_create_new_entity(B2B_CLIENT, 0, &new_dest, 0, 0, 0, 0, 0); if(entity == NULL) { LM_ERR("Failed to create new b2b entity\n"); goto free; } lock_get(&b2bl_htable[hash_index].lock); tuple = b2bl_search_tuple_safe(hash_index, local_index); if(tuple == NULL) { LM_ERR("No entity found\n"); goto error; } bridging_entity = tuple->bridge_entities[entity_no]; old_entity = tuple->bridge_entities[(entity_no?0:1)]; if(old_entity == NULL || bridging_entity == NULL) { LM_ERR("Wrong dialog id\n"); goto error; } if(old_entity->next || old_entity->prev) { LM_ERR("Can not disconnect entity [%p]\n", old_entity); b2bl_print_tuple(tuple, L_ERR); goto error; } /* send BYE to old client */ if(old_entity->disconnected) { memset(&rpl_data, 0, sizeof(b2b_rpl_data_t)); PREP_RPL_DATA(old_entity); rpl_data.method =METHOD_BYE; rpl_data.code =200; rpl_data.text =&ok; b2b_api.send_reply(&rpl_data); } else { old_entity->disconnected = 1; memset(&req_data, 0, sizeof(b2b_req_data_t)); PREP_REQ_DATA(old_entity); req_data.method =&meth_bye; b2b_api.send_request(&req_data); } if (0 == b2bl_drop_entity(old_entity, tuple)) { LM_ERR("Inconsistent tuple [%p]\n", tuple); b2bl_print_tuple(tuple, L_ERR); goto error; } if (old_entity->peer->peer == old_entity) old_entity->peer->peer = NULL; else { LM_ERR("Unexpected chain: old_entity=[%p] and old_entity->peer->peer=[%p]\n", old_entity, old_entity->peer->peer); goto error; } old_entity->peer = NULL; tuple->bridge_entities[0]= bridging_entity; if (prov_entity) { tuple->bridge_entities[1]= prov_entity; tuple->bridge_entities[2]= entity; /* we don't have to free it anymore */ prov_entity = 0; } else { tuple->bridge_entities[1]= entity; bridging_entity->peer = entity; entity->peer = bridging_entity; } tuple->scenario_state = B2B_BRIDGING_STATE; bridging_entity->state = 0; memset(&req_data, 0, sizeof(b2b_req_data_t)); PREP_REQ_DATA(bridging_entity); req_data.method =&meth_inv; b2b_api.send_request(&req_data); lock_release(&b2bl_htable[hash_index].lock); return init_mi_tree(200, "OK", 2); error: if(tuple) b2b_mark_todel(tuple); lock_release(&b2bl_htable[hash_index].lock); free: if (prov_entity) shm_free(prov_entity); return 0; }
/** * Parses the PING configuration string. Its format is * "ping_period:pings_lost:ping_timeout" * ping_period : time between pings * pings_lost: number of lost pings before failure * ping_timeout: time to consider a ping failed * * returns * 0 if no clusters present * -1 if config is malformed (unable to parse); * 1 if config is successfully set */ int parse_cluster_cfg(void) { char *p,*start; int n,k; struct as_entry **entry,*tmp,*tmp2; if((p=cluster_cfg)==0 || *cluster_cfg==0){ return 0; } entry=&as_list; while (*p) { eat_spaces(p); /*get cluster name*/ start = p; while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0) p++; if ( p==start || *p==0 ){ LM_ERR("cluster names must only contain alphanumeric chars\n"); goto error; } if (!((*entry)=(struct as_entry*)shm_malloc(sizeof(struct as_entry)))) { LM_ERR("Out of shm mem for as_entry\n"); goto error; } memset(*entry,0,sizeof(struct as_entry)); if (!((*entry)->name.s=shm_malloc(p-start))) { LM_ERR("Out of shm malloc for cluster name\n"); goto error; } memcpy((*entry)->name.s, start, p-start); (*entry)->name.len=p-start; (*entry)->connected=0; (*entry)->type=CLUSTER_TYPE; (*entry)->u.cs.name=(*entry)->name; /*get as names*/ eat_spaces(p); if (*p!='['){ LM_ERR("Malformed cluster cfg string %s\n",cluster_cfg); goto error; } p++; n=0; while (*p!=']') { eat_spaces(p); start = p; while(*p!=' ' && *p!='\t' && *p!=']' && *p!=',' && *p!=0) p++; if ( p==start || *p==0 ) goto error; if (!((*entry)->u.cs.as_names[n].s=shm_malloc(p-start))) { LM_ERR("Out of shm_mem for AS name in cluster\n"); goto error; } (*entry)->u.cs.as_names[n].len=p-start; memcpy((*entry)->u.cs.as_names[n].s,start,p-start); n++; if(n>=MAX_AS_PER_CLUSTER){ LM_ERR("too many AS per cluster\n"); goto error; } eat_spaces(p); if (*p==',') { p++; eat_spaces(p); } } p++; (*entry)->u.cs.num=n; /* end of element */ eat_spaces(p); if (*p==',') p++; eat_spaces(p); entry=&((*entry)->next); } for (tmp=as_list;tmp->next;tmp=tmp->next){ LM_DBG("%.*s\n",tmp->name.len,tmp->name.s); } LM_DBG("%.*s\n",tmp->name.len,tmp->name.s); entry=&(tmp->next); for(tmp=as_list;tmp;tmp=tmp->next){ if (tmp->type!=CLUSTER_TYPE) continue; LM_DBG("cluster:[%.*s]\n",tmp->name.len,tmp->name.s); for(k=0;k<tmp->u.cs.num;k++){ LM_DBG("\tAS:[%.*s]\n",tmp->u.cs.as_names[k].len,tmp->u.cs.as_names[k].s); for (tmp2=as_list;tmp2;tmp2=tmp2->next) { if (tmp2->type== AS_TYPE && tmp->u.cs.as_names[k].len == tmp2->name.len && !memcmp(tmp->u.cs.as_names[k].s,tmp2->name.s,tmp2->name.len)) { tmp->u.cs.servers[k]=&tmp2->u.as; break; } } if(tmp2) continue; if (!((*entry)=shm_malloc(sizeof(struct as_entry)))) { LM_ERR("Out of shm mem \n"); goto error; } memset(*entry,0,sizeof(struct as_entry)); (*entry)->type=AS_TYPE; if (!((*entry)->name.s=shm_malloc(tmp->u.cs.as_names[k].len))) { LM_ERR("out of shm mem\n"); goto error; } memcpy((*entry)->name.s,tmp->u.cs.as_names[k].s,tmp->u.cs.as_names[k].len); (*entry)->name.len=tmp->u.cs.as_names[k].len; (*entry)->u.as.name=(*entry)->name; tmp->u.cs.servers[k]=&(*entry)->u.as; entry=&((*entry)->next); } } for(tmp=as_list;tmp;tmp=tmp->next){ LM_DBG("%.*s %s",tmp->name.len,tmp->name.s,tmp->next?"":"\n"); } return 1; error: tmp=as_list; while(tmp){ for(k=0;k<tmp->u.cs.num;k++){ if(tmp->u.cs.as_names[k].s) shm_free(tmp->u.cs.as_names[k].s); } if(tmp->name.s) shm_free(tmp->name.s); tmp2=tmp; tmp=tmp->next; shm_free(tmp2); } as_list=(struct as_entry *)0; return -1; }
subs_t* mem_copy_subs_noc(subs_t* s) { int size; subs_t* dest; size= sizeof(subs_t)+ (s->pres_uri.len+ s->to_user.len + s->to_domain.len+ s->from_user.len+ s->from_domain.len+ s->callid.len + s->to_tag.len+ s->from_tag.len+s->sockinfo_str.len+s->event_id.len + s->local_contact.len + s->record_route.len+ + s->reason.len+ s->watcher_user.len+ s->watcher_domain.len + 1)*sizeof(char); dest= (subs_t*)shm_malloc(size); if(dest== NULL) { ERR_MEM(SHARE_MEM); } memset(dest, 0, size); size= sizeof(subs_t); CONT_COPY(dest, dest->pres_uri, s->pres_uri) CONT_COPY(dest, dest->to_user, s->to_user) CONT_COPY(dest, dest->to_domain, s->to_domain) CONT_COPY(dest, dest->from_user, s->from_user) CONT_COPY(dest, dest->from_domain, s->from_domain) CONT_COPY(dest, dest->watcher_user, s->watcher_user) CONT_COPY(dest, dest->watcher_domain, s->watcher_domain) CONT_COPY(dest, dest->to_tag, s->to_tag) CONT_COPY(dest, dest->from_tag, s->from_tag) CONT_COPY(dest, dest->callid, s->callid) CONT_COPY(dest, dest->sockinfo_str, s->sockinfo_str) CONT_COPY(dest, dest->local_contact, s->local_contact) CONT_COPY(dest, dest->record_route, s->record_route) if(s->event_id.s) CONT_COPY(dest, dest->event_id, s->event_id) if(s->reason.s) CONT_COPY(dest, dest->reason, s->reason) dest->event= s->event; dest->local_cseq= s->local_cseq; dest->remote_cseq= s->remote_cseq; dest->status= s->status; dest->version= s->version; dest->send_on_cback= s->send_on_cback; dest->expires= s->expires; dest->db_flag= s->db_flag; dest->contact.s= (char*)shm_malloc(s->contact.len* sizeof(char)); if(dest->contact.s== NULL) { ERR_MEM(SHARE_MEM); } memcpy(dest->contact.s, s->contact.s, s->contact.len); dest->contact.len= s->contact.len; return dest; error: if(dest) shm_free(dest); return NULL; }
int rtjson_init_routes(sip_msg_t *msg, str *rdoc) { srjson_Hooks jhooks; srjson_doc_t *tdoc = NULL; sr_data_t *xdata = NULL; rtjson_data_t *rdata = NULL; sr_xavp_t *xavp=NULL; str xname; sr_xval_t xval; memset(&jhooks, 0, sizeof(srjson_Hooks)); jhooks.malloc_fn = rtjson_malloc; jhooks.free_fn = rtjson_free; tdoc = srjson_NewDoc(&jhooks); if(tdoc==NULL) { LM_ERR("no more shm\n"); return -1; } tdoc->root = srjson_Parse(tdoc, rdoc->s); if(tdoc->root == NULL) { LM_ERR("invalid json doc [[%s]]\n", rdoc->s); srjson_DeleteDoc(tdoc); return -1; } xdata = shm_malloc(sizeof(sr_data_t)); if(xdata==NULL) { LM_ERR("no more shm\n"); srjson_DeleteDoc(tdoc); return -1; } memset(xdata, 0, sizeof(sr_data_t)); rdata = shm_malloc(sizeof(rtjson_data_t)); if(rdata==NULL) { LM_ERR("no more shm\n"); srjson_DeleteDoc(tdoc); shm_free(xdata); return -1; } memset(rdata, 0, sizeof(rtjson_data_t)); rdata->jdoc = tdoc; xdata->p = rdata; xdata->pfree = rtjson_data_free; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = *rdoc; xname.s = "json"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_DATA; xval.v.data = xdata; xname.s = "data"; xname.len = 4; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { goto error; } /* reset pointers - they are linked inside xavp now */ tdoc = NULL; xdata = NULL; rdata = NULL; memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; xval.v.xavp = xavp; if(xavp_add_value(&_rtjson_xavp_name, &xval, NULL)==NULL) { goto error; } return 0; error: if(xavp) xavp_destroy_list(&xavp); if(rdata) shm_free(rdata); if(xdata) shm_free(xdata); if(tdoc) srjson_DeleteDoc(tdoc); return -1; }