/* * Add a new domain name to did */ static int domain_add(domain_t* d, str* domain, unsigned int flags) { str* p1; unsigned int* p2; str dom; if (!d || !domain) { ERR("Invalid parameter value\n"); return -1; } dom.s = shm_malloc(domain->len); if (!dom.s) goto error; memcpy(dom.s, domain->s, domain->len); dom.len = domain->len; strlower(&dom); p1 = (str*)shm_realloc(d->domain, sizeof(str) * (d->n + 1)); if (!p1) goto error; p2 = (unsigned int*)shm_realloc(d->flags, sizeof(unsigned int) * (d->n + 1)); if (!p2) goto error; d->domain = p1; d->domain[d->n] = dom; d->flags = p2; d->flags[d->n] = flags; d->n++; return 0; error: ERR("Unable to add new domain name (out of memory)\n"); if (dom.s) shm_free(dom.s); return -1; }
static inline module_stats* add_stat_module( char *module) { module_stats *amods; module_stats *mods; int len; if ( (module==0) || ((len = strlen(module))==0 ) ) return 0; amods = (module_stats*)shm_realloc( collector->amodules, (collector->mod_no+1)*sizeof(module_stats) ); if (amods==0) { LM_ERR("no more shm memory\n"); return 0; } collector->amodules = amods; collector->mod_no++; mods = &amods[collector->mod_no-1]; memset( mods, 0, sizeof(module_stats) ); mods->name.s = module; mods->name.len = len; return mods; }
static int lb_set_resource_bitmask(struct lb_resource *res, unsigned int bit) { #define BITMAP_UNIT 4 unsigned int size; if ( bit >= res->bitmap_size*8*sizeof(unsigned int) ) { size = (bit / (8*sizeof(unsigned int)))+1; size = ((size+BITMAP_UNIT-1) / BITMAP_UNIT ) * BITMAP_UNIT; LM_DBG("realloc the bitmap for bit %u - old size=%u; new size=%u\n", bit, res->bitmap_size, size); res->dst_bitmap = (unsigned int*)shm_realloc( res ->dst_bitmap, size*sizeof(unsigned int)); if (res->dst_bitmap==NULL) { LM_ERR("failed to realloc (shm) bitmap\n"); return -1; } /* set to zero the new allocated bitmap part */ memset( res->dst_bitmap+res->bitmap_size, 0, (size-res->bitmap_size)*sizeof(unsigned int) ); res->bitmap_size = size; } /* set the bit */ size = bit / (8*sizeof(unsigned int)); LM_DBG("setting bit %u in unit %u , pos %d\n", bit, size, bit % ((unsigned int)(8*sizeof(unsigned int)))); res->dst_bitmap[size] |= 1<<( bit % (8*sizeof(unsigned int)) ); return 0; }
static inline int store_acc_table(acc_ctx_t* ctx, str* table) { if (ctx == NULL || table == NULL || table->s == NULL || table->len == 0) { LM_ERR("bad usage!\n"); return -1; } if (ctx->acc_table.s && ctx->acc_table.len) { if (table->len > ctx->acc_table.len) { ctx->acc_table.s = shm_realloc(ctx->acc_table.s, table->len * sizeof(char)); if (ctx->acc_table.s == NULL) goto memerr; } } else { ctx->acc_table.s = shm_malloc(table->len * sizeof(char)); if (ctx->acc_table.s == NULL) goto memerr; } memcpy(ctx->acc_table.s, table->s, table->len); ctx->acc_table.len = table->len; return 0; memerr: LM_ERR("no more shm!\n"); return -1; }
/* creats a new thread, set the thread attributes, its name and * adds the thread to the Thread Table * IMPORTANT: to be called only by attendent!! */ int pt_create_thread(char *name, void *(*thread_routine)(void*), void *arg) { pthread_t tp; /* add a new TT record */ tt = (struct thread_info*)shm_realloc ( tt, (threads_counter+1)*sizeof(struct thread_info) ); if (tt==NULL) { LM_ERR("no more shared memory - failed to realloc\n"); return -1; } memset( tt+threads_counter, 0, sizeof(struct thread_info)); /* fill in the thread info */ strncpy( tt[threads_counter].name, name, MAX_TT_NAME-1); tt[threads_counter].thread_routine = thread_routine; tt[threads_counter].thread_arg = arg; if (pthread_create(&tp,NULL,thread_startup,(void*)(long)threads_counter)<0){ LM_ERR("failed to create new thread <%s> (counter=%d)\n", name, threads_counter); return -1; } tt[threads_counter].id = tp; threads_counter ++; return 0; }
/* move r_cseq to prev_cseq in leg */ static inline int switch_cseqs(struct dlg_cell *dlg,unsigned int leg_no) { str* r_cseq,*prev_cseq; r_cseq = &dlg->legs[leg_no].r_cseq; prev_cseq = &dlg->legs[leg_no].prev_cseq; if ( prev_cseq->s ) { if (prev_cseq->len < r_cseq->len) { prev_cseq->s = (char*)shm_realloc(prev_cseq->s,r_cseq->len); if (prev_cseq->s==NULL) { LM_ERR("no more shm mem for realloc (%d)\n",r_cseq->len); return -1; } } } else { prev_cseq->s = (char*)shm_malloc(r_cseq->len); if (prev_cseq->s==NULL) { LM_ERR("no more shm mem for malloc (%d)\n",r_cseq->len); return -1; } } memcpy( prev_cseq->s, r_cseq->s, r_cseq->len ); prev_cseq->len = r_cseq->len; LM_DBG("prev_cseq = %.*s for leg %d\n",prev_cseq->len,prev_cseq->s,leg_no); return 0; }
/* * create/add new row to the leg matrix * initialize all values in current row with null * * */ int expand_legs(acc_ctx_t* ctx) { if (ctx == NULL) { LM_ERR("bad usage!\n"); return -1; } if (ctx->leg_values == NULL) { ctx->leg_values = shm_malloc(LEG_MATRIX_ALLOC_FACTOR * sizeof(leg_value_p)); ctx->allocated_legs = LEG_MATRIX_ALLOC_FACTOR; } else if (ctx->legs_no + 1 == ctx->allocated_legs) { ctx->leg_values = shm_realloc(ctx->leg_values, (ctx->allocated_legs + LEG_MATRIX_ALLOC_FACTOR) * sizeof(leg_value_p)); ctx->allocated_legs += LEG_MATRIX_ALLOC_FACTOR; } if (ctx->leg_values == NULL) { LM_ERR("no more shm!\n"); return -1; } return build_acc_extra_array(leg_tags, leg_tgs_len, &ctx->leg_values[ctx->legs_no++]); }
int add_url(int index, char * name) { LM_DBG("add url (%i . %s)\n", index, name); int i; LM_DBG("add another url %p\n", global->set_list[index].db_list); /* realoc */ i = global->set_list[index].size; /* db_list realloc */ global->set_list[index].db_list = (info_db_t *) shm_realloc(global->set_list[index].db_list, (i+1)* sizeof(info_db_t)); if(!global->set_list[index].db_list) MEM_ERR(MEM_SHM); global->set_list[index].size++; /* db_url */ global->set_list[index].db_list[i].db_url.s = (char *) shm_malloc(strlen(name) * sizeof(char)); global->set_list[index].db_list[i].db_url.len = strlen(name); memcpy(global->set_list[index].db_list[i].db_url.s, name, strlen(name)); global->set_list[index].db_list[i].flags = CAN_USE | MAY_USE; return 0; error: return 1; }
int dlg_update_routing(struct dlg_cell *dlg, unsigned int leg, str *rr, str *contact, str *sdp ) { rr_t *head = NULL, *rrp; LM_DBG("dialog %p[%d]: rr=<%.*s> contact=<%.*s>\n", dlg, leg, rr->len,rr->s, contact->len,contact->s ); if (dlg->legs[leg].contact.s) shm_free(dlg->legs[leg].contact.s); dlg->legs[leg].contact.s = shm_malloc(rr->len + contact->len); if (dlg->legs[leg].contact.s==NULL) { LM_ERR("no more shm mem\n"); return -1; } dlg->legs[leg].contact.len = contact->len; memcpy( dlg->legs[leg].contact.s, contact->s, contact->len); /* rr */ if (rr->len) { dlg->legs[leg].route_set.s = dlg->legs[leg].contact.s + contact->len; dlg->legs[leg].route_set.len = rr->len; memcpy( dlg->legs[leg].route_set.s, rr->s, rr->len); /* also update URI pointers */ if (parse_rr_body(dlg->legs[leg].route_set.s, dlg->legs[leg].route_set.len,&head) != 0) { LM_ERR("failed parsing route set\n"); shm_free(dlg->legs[leg].contact.s); return -1; } rrp = head; dlg->legs[leg].nr_uris = 0; while (rrp) { dlg->legs[leg].route_uris[dlg->legs[leg].nr_uris++] = rrp->nameaddr.uri; rrp = rrp->next; } free_rr(&head); } if (sdp && sdp->len && sdp->s) { dlg->legs[leg].sdp.s = shm_realloc(dlg->legs[leg].sdp.s,sdp->len); if (!dlg->legs[leg].sdp.s) { LM_ERR("Failed to allocate mem for the SDP\n"); return -1; } dlg->legs[leg].sdp.len = sdp->len; memcpy(dlg->legs[leg].sdp.s,sdp->s,sdp->len); } return 0; }
event_id_t evi_publish_event(str event_name) { int idx; if (event_name.len > MAX_EVENT_NAME) { LM_ERR("event name too long [%d>%d]\n", event_name.len, MAX_EVENT_NAME); return EVI_ERROR; } for (idx = 0; idx < events_no; idx++) { if (events[idx].name.len == event_name.len && !memcmp(events[idx].name.s, event_name.s, event_name.len)) { LM_WARN("Event \"%.*s\" was previously published\n", event_name.len, event_name.s); return idx; } } /* check if the event was already registered */ if (!events) { /* first event */ events = shm_malloc(max_alloc_events * sizeof(evi_event_t)); if (!events) { LM_ERR("no more shm memory to hold %d events\n", max_alloc_events); return EVI_ERROR; } } else if (events_no == max_alloc_events) { max_alloc_events *= 2; events = shm_realloc(events, max_alloc_events); if (!events) { LM_ERR("no more shm memory to hold %d events\n", max_alloc_events); return EVI_ERROR; } } events[events_no].lock = lock_alloc(); if (!events[events_no].lock) { LM_ERR("Failed to allocate subscribers lock\n"); return EVI_ERROR; } events[events_no].lock = lock_init(events[events_no].lock); if (!events[events_no].lock) { LM_ERR("Failed to create subscribers lock\n"); return EVI_ERROR; } events[events_no].id = events_no; events[events_no].name.s = event_name.s; events[events_no].name.len = event_name.len; events[events_no].subscribers = NULL; LM_DBG("Registered event <%.*s(%d)>\n", event_name.len, event_name.s, events_no); return events_no++; }
/* * set pv_value_t in pkg to pv_value_t from extra in shm * * * if it's an integer then convert it to string and set the string value * to the shm pv_value_t * * if it's a string then try converting it to it */ int set_value_shm(pv_value_t* pvt, extra_value_t* extra) { if (pvt == NULL) { LM_ERR("bad value!\n"); return -1; } if (pvt->flags&PV_TYPE_INT || pvt->flags&PV_VAL_STR) { if (pvt->flags&PV_TYPE_INT || pvt->flags&PV_VAL_INT) { /* transform the int value into a string */ pvt->rs.s = int2str(pvt->ri, &pvt->rs.len); pvt->flags |= PV_VAL_STR; } else { /* it's PV_VAL_STR; check whether it is an integer value */ if (str2sint(&pvt->rs, &pvt->ri) == 0) { pvt->flags |= PV_TYPE_INT|PV_VAL_INT; } } if (extra->shm_buf_len == 0) { extra->value.s = shm_malloc(pvt->rs.len); extra->shm_buf_len = extra->value.len = pvt->rs.len; } else if (extra->shm_buf_len < pvt->rs.len) { extra->value.s = shm_realloc(extra->value.s, pvt->rs.len); extra->shm_buf_len = extra->value.len = pvt->rs.len; } else { extra->value.len = pvt->rs.len; } if (extra->value.s == NULL) goto memerr; memcpy(extra->value.s, pvt->rs.s, pvt->rs.len); } else if (pvt->flags&PV_VAL_NULL) { if (extra->shm_buf_len) { shm_free(extra->value.s); extra->shm_buf_len = 0; } extra->value.s = NULL; extra->value.len = 0; } else { LM_ERR("invalid pvt value!\n"); return -1; } return 0; memerr: LM_ERR("No more shm!\n"); return -1; }
int add_set(char * name, char * mode) { int nmode = 0; if(strncmp(mode, "FAILOVER", strlen("FAILOVER")) == 0) nmode = FAILOVER; else if(strncmp(mode, "PARALLEL", strlen("PARALLEL")) == 0) nmode = PARALLEL; else if(strncmp(mode, "ROUND", strlen("ROUND")) == 0) nmode = ROUND; LM_DBG("add set=%s mode=%i\n", name, nmode); if (!global) { global = shm_malloc(sizeof *global); if (!global) MEM_ERR(MEM_SHM); memset(global, 0, sizeof *global); } /* realloc set_list */ int i = global->size; global->set_list = (info_set_t *)shm_realloc(global->set_list, (i+1)*sizeof(info_set_t)); if(!global->set_list) MEM_ERR(MEM_SHM); memset(&global->set_list[i], 0, sizeof *global->set_list); global->size++; global->set_list[i].set_name.s = (char *) shm_malloc(strlen(name)*sizeof(char)); global->set_list[i].set_name.len = strlen(name); memcpy(global->set_list[i].set_name.s, name, strlen(name)); /* set mode */ global->set_list[i].set_mode = nmode; global->set_list[i].size = 0; return 0; error: return 1; }
int dlg_save_del_vias(struct sip_msg* req, struct dlg_leg* leg) { struct hdr_field *it; int size=0; char* p, *buf; for (it=req->h_via1;it;it=it->sibling) size+= it->len; if(size > leg->last_vias.len) { leg->last_vias.s = (char*)shm_realloc(leg->last_vias.s, size); if(leg->last_vias.s == NULL) { LM_ERR("no more shared memory\n"); return -1; } } buf = req->buf; p = leg->last_vias.s; it = req->h_via1; if(it) { /* delete first via1 to set the type (the build_req_buf_from_sip_req will know not to add lump in via1)*/ memcpy(p, it->name.s, it->len); p+= it->len; if (del_lump(req,it->name.s - buf,it->len, 0) == 0) { LM_ERR("del_lump failed \n"); return -1; } LM_DBG("Delete via [%.*s]\n", it->len, it->name.s); for (it=it->sibling; it; it=it->sibling) { memcpy(p, it->name.s, it->len); p+= it->len; if (del_lump(req,it->name.s - buf,it->len, 0) == 0) { LM_ERR("del_lump failed \n"); return -1; } LM_DBG("Delete via [%.*s]\n", it->len, it->name.s); } } leg->last_vias.len = size; LM_DBG("[leg= %p] last_vias: %.*s\n", leg, size, leg->last_vias.s); return 0; }
/* XXX: realloc() is not checked! */ void sipwatch_add(const char *str, int len) { char *ext; lock_get(&siplua_watch->lock); ext = shm_malloc(len + 1); if (ext) { memcpy(ext, str, len); ext[len] = '\0'; siplua_watch->ext = shm_realloc(siplua_watch->ext, (siplua_watch->nb + 1) * sizeof(struct siplua_watch_ext)); siplua_watch->ext[siplua_watch->nb].str = ext; siplua_watch->ext[siplua_watch->nb].crc = ssh_crc32((unsigned char *)str, len); ++siplua_watch->nb; } lock_release(&siplua_watch->lock); }
int header_list_add(struct header_list *hl, str* hdr) { char *tmp; hl->len++; hl->t = shm_realloc(hl->t, hl->len * sizeof(char*)); if (!hl->t) { LM_ERR("shm memory allocation failure\n"); return -1; } hl->t[hl->len - 1] = shm_malloc(hdr->len + 1); tmp = hl->t[hl->len - 1]; if (!tmp) { LM_ERR("shm memory allocation failure\n"); return -1; } memcpy(tmp, hdr->s, hdr->len); *(tmp + hdr->len) = '\0'; LM_DBG("stored new http header: [%s]\n", tmp); return 1; }
void sipwatch_delete(const char *str, int len) { int i; u_int32_t crc; crc = ssh_crc32((unsigned char *)str, len); lock_get(&siplua_watch->lock); for (i = 0; i < siplua_watch->nb; ++i) { if (siplua_watch->ext[i].crc == crc) { memmove(&siplua_watch->ext[i], &siplua_watch->ext[i + 1], siplua_watch->nb - i - 1); siplua_watch->ext = shm_realloc(siplua_watch->ext, (siplua_watch->nb - 1) * sizeof(struct siplua_watch_ext)); --siplua_watch->nb; --i; } } lock_release(&siplua_watch->lock); }
/* update cseq filed in leg * if inv = 1, update the inv_cseq field * else, update the r_cseq */ int dlg_update_cseq(struct dlg_cell * dlg, unsigned int leg, str *cseq,int inv) { str* update_cseq; if (inv == 1) update_cseq = &dlg->legs[leg].inv_cseq; else update_cseq = &dlg->legs[leg].r_cseq; if ( update_cseq->s ) { if (update_cseq->len < cseq->len) { update_cseq->s = (char*)shm_realloc(update_cseq->s,cseq->len); if (update_cseq->s==NULL) { LM_ERR("no more shm mem for realloc (%d)\n",cseq->len); goto error; } } } else { update_cseq->s = (char*)shm_malloc(cseq->len); if (update_cseq->s==NULL) { LM_ERR("no more shm mem for malloc (%d)\n",cseq->len); goto error; } } memcpy( update_cseq->s, cseq->s, cseq->len ); update_cseq->len = cseq->len; if (inv == 1) LM_DBG("dlg %p[%d]: last invite cseq is %.*s\n", dlg,leg, dlg->legs[leg].inv_cseq.len, dlg->legs[leg].inv_cseq.s); else LM_DBG("dlg %p[%d]: cseq is %.*s\n", dlg,leg, dlg->legs[leg].r_cseq.len, dlg->legs[leg].r_cseq.s); return 0; error: LM_ERR("not more shm mem\n"); return -1; }
int lcache_htable_add(cachedb_con *con,str *attr,int val,int expires,int *new_val) { int hash_code; lcache_entry_t *it=NULL,*it_prev=NULL; int old_value; char *new_value; int new_len; str ins_val; struct timeval start; start_expire_timer(start,local_exec_threshold); hash_code = core_hash(attr,0,cache_htable_size); lock_get(&cache_htable[hash_code].lock); it = cache_htable[hash_code].entries; while (it) { if (it->attr.len == attr->len && memcmp(it->attr.s,attr->s,attr->len) == 0) { if (it->expires !=0 && it->expires < get_ticks()) { /* found an expired entry -> delete it */ if(it_prev) it_prev->next = it->next; else cache_htable[hash_code].entries = it->next; shm_free(it); lock_release(&cache_htable[hash_code].lock); ins_val.s = sint2str(val,&ins_val.len); if (lcache_htable_insert(con,attr,&ins_val,expires) < 0) { LM_ERR("failed to insert value\n"); stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return -1; } if (new_val) *new_val = val; stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return 0; } /* found our valid entry */ if (str2sint(&it->value,&old_value) < 0) { LM_ERR("not an integer\n"); lock_release(&cache_htable[hash_code].lock); stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return -1; } old_value+=val; expires = it->expires; new_value = sint2str(old_value,&new_len); it = shm_realloc(it,sizeof(lcache_entry_t) + attr->len +new_len); if (it == NULL) { LM_ERR("failed to realloc struct\n"); lock_release(&cache_htable[hash_code].lock); stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return -1; } if (it_prev) it_prev->next = it; else cache_htable[hash_code].entries = it; it->attr.s = (char*)(it + 1); it->value.s =(char *)(it + 1) + attr->len; it->expires = expires; memcpy(it->value.s,new_value,new_len); it->value.len = new_len; lock_release(&cache_htable[hash_code].lock); if (new_val) *new_val = old_value; stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return 0; } it_prev = it; it = it->next; } lock_release(&cache_htable[hash_code].lock); /* not found */ ins_val.s = sint2str(val,&ins_val.len); if (lcache_htable_insert(con,attr,&ins_val,expires) < 0) { LM_ERR("failed to insert value\n"); stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return -1; } if (new_val) *new_val = val; stop_expire_timer(start,local_exec_threshold, "cachedb_local add",attr->s,attr->len,0); return 0; }
int set_all_domain_attr(struct tls_domain **dom, char **str_vals, int *int_vals, str* blob_vals) { size_t len; char *p; struct tls_domain *d = *dom; size_t cadir_len = strlen(str_vals[STR_VALS_CADIR_COL]); size_t cplist_len = strlen(str_vals[STR_VALS_CPLIST_COL]); size_t crl_dir_len = strlen(str_vals[STR_VALS_CRL_DIR_COL]); size_t eccurve_len = strlen(str_vals[STR_VALS_ECCURVE_COL]); char name_buf[255]; int name_len; len = sizeof(struct tls_domain) + d->name.len; if (cadir_len) len += cadir_len + 1; if (cplist_len) len += cplist_len + 1; if (crl_dir_len) len += crl_dir_len + 1; if (eccurve_len) len += eccurve_len + 1; if(blob_vals[BLOB_VALS_CERTIFICATE_COL].len && blob_vals[BLOB_VALS_CERTIFICATE_COL].s) len += blob_vals[BLOB_VALS_CERTIFICATE_COL].len; if(blob_vals[BLOB_VALS_PK_COL].len && blob_vals[BLOB_VALS_PK_COL].s) len += blob_vals[BLOB_VALS_PK_COL].len; if(blob_vals[BLOB_VALS_CALIST_COL].len && blob_vals[BLOB_VALS_CALIST_COL].s) len += blob_vals[BLOB_VALS_CALIST_COL].len; if(blob_vals[BLOB_VALS_DHPARAMS_COL].len && blob_vals[BLOB_VALS_DHPARAMS_COL].s) len += blob_vals[BLOB_VALS_DHPARAMS_COL].len; memcpy(name_buf, d->name.s, d->name.len); name_len = d->name.len; d = shm_realloc(d, len); if (d == NULL) { LM_ERR("insufficient shm memory"); d = *dom; *dom = (*dom)->next; shm_free(d); return -1; } *dom = d; if (strcasecmp(str_vals[STR_VALS_METHOD_COL], "SSLV23") == 0 || strcasecmp(str_vals[STR_VALS_METHOD_COL], "TLSany") == 0) d->method = TLS_USE_SSLv23; else if (strcasecmp(str_vals[STR_VALS_METHOD_COL], "TLSV1") == 0) d->method = TLS_USE_TLSv1; else if (strcasecmp(str_vals[STR_VALS_METHOD_COL], "TLSV1_2") == 0) d->method = TLS_USE_TLSv1_2; if (int_vals[INT_VALS_VERIFY_CERT_COL] != -1) { d->verify_cert = int_vals[INT_VALS_VERIFY_CERT_COL]; } if (int_vals[INT_VALS_CRL_CHECK_COL] != -1) { d->crl_check_all = int_vals[INT_VALS_CRL_CHECK_COL]; } if (int_vals[INT_VALS_REQUIRE_CERT_COL] != -1) { d->require_client_cert = int_vals[INT_VALS_REQUIRE_CERT_COL]; } p = (char *) (d + 1); d->name.s = p; d->name.len = name_len; memcpy(p, name_buf, name_len); p = p + d->name.len; memset(p, 0, len - (sizeof(struct tls_domain) + d->name.len)); if (cadir_len) { d->ca_directory = p; memcpy(p, str_vals[STR_VALS_CADIR_COL], cadir_len); p = p + cadir_len + 1; } if (blob_vals[BLOB_VALS_CALIST_COL].len && blob_vals[BLOB_VALS_CALIST_COL].s) { d->ca.s = p; d->ca.len = blob_vals[BLOB_VALS_CALIST_COL].len; memcpy(p, blob_vals[BLOB_VALS_CALIST_COL].s, blob_vals[BLOB_VALS_CALIST_COL].len); p = p + d->ca.len; } if (blob_vals[BLOB_VALS_CERTIFICATE_COL].len && blob_vals[BLOB_VALS_CERTIFICATE_COL].s) { d->cert.s = p; d->cert.len = blob_vals[BLOB_VALS_CERTIFICATE_COL].len; memcpy(p, blob_vals[BLOB_VALS_CERTIFICATE_COL].s, blob_vals[BLOB_VALS_CERTIFICATE_COL].len); p = p + d->cert.len; } if (cplist_len) { d->ciphers_list = p; memcpy(p, str_vals[STR_VALS_CPLIST_COL], cplist_len); p = p + cplist_len + 1; } if (crl_dir_len) { d->crl_directory = p; memcpy(p, str_vals[STR_VALS_CRL_DIR_COL], crl_dir_len); p = p + crl_dir_len + 1; } if (blob_vals[BLOB_VALS_DHPARAMS_COL].len && blob_vals[BLOB_VALS_DHPARAMS_COL].s) { d->dh_param.s = p; d->dh_param.len = blob_vals[BLOB_VALS_DHPARAMS_COL].len; memcpy(p, blob_vals[BLOB_VALS_DHPARAMS_COL].s, blob_vals[BLOB_VALS_DHPARAMS_COL].len); p = p + d->dh_param.len; } if (eccurve_len) { d->tls_ec_curve = p; memcpy(p, str_vals[STR_VALS_ECCURVE_COL], eccurve_len); p = p + eccurve_len + 1; } if (blob_vals[BLOB_VALS_PK_COL].len && blob_vals[BLOB_VALS_PK_COL].s) { d->pkey.s = p; d->pkey.len = blob_vals[BLOB_VALS_PK_COL].len; memcpy(p, blob_vals[BLOB_VALS_PK_COL].s, blob_vals[BLOB_VALS_PK_COL].len); p = p + d->pkey.len; } return 0; }
static void * ser_realloc(void *ptr, size_t size) { return shm_realloc(ptr, size); }
int ds_pvar_algo(struct sip_msg *msg, ds_set_p set, ds_dest_p **sorted_set) { pv_value_t val; int i, j, k, end_idx, cnt; ds_dest_p *sset; ds_pvar_param_p param; if (!set) { LM_ERR("invalid set\n"); return -1; } sset = shm_realloc(*sorted_set, set->nr * sizeof(ds_dest_p)); if (!sset) { LM_ERR("no more shm memory\n"); return -1; } *sorted_set = sset; end_idx = set->nr - 1; if (ds_use_default) { sset[end_idx] = &set->dlist[end_idx]; end_idx--; } for (i = 0, cnt = 0; i < set->nr - (ds_use_default?1:0); i++) { if (set->dlist[i].flags & (DS_INACTIVE_DST|DS_PROBING_DST)) { /* move to the end of the list */ sset[end_idx--] = &set->dlist[i]; continue; } /* if pvar not set - try to evaluate it */ if (set->dlist[i].param == NULL) { param = ds_get_pvar_param(set->dlist[i].uri); if (param == NULL) { LM_ERR("cannot parse pvar for uri %.*s\n", set->dlist[i].uri.len, set->dlist[i].uri.s); continue; } set->dlist[i].param = (void *)param; } else { param = (ds_pvar_param_p)set->dlist[i].param; } if (pv_get_spec_value(msg, ¶m->pvar, &val) < 0) { LM_ERR("cannot get spec value for spec %.*s\n", set->dlist[i].uri.len, set->dlist[i].uri.s); continue; } if (!(val.flags & PV_VAL_NULL)) { if (!(val.flags & PV_VAL_INT)) { /* last attempt to retrieve value */ if (!str2sint(&val.rs, ¶m->value)) { LM_ERR("invalid pvar value type - not int\n"); continue; } } else { param->value = val.ri; } } else { param->value = 0; } /* search the proper position */ j = 0; for (; j < cnt && ((ds_pvar_param_p)sset[j]->param)->value <= param->value; j++); /* make space for the new entry */ for (k = cnt; k > j; k--) sset[k] = sset[k - 1]; sset[j] = &set->dlist[i]; cnt++; } return cnt; }
static inline int pre_print_uac_request( struct cell *t, int branch, struct sip_msg *request, struct sip_msg_body **body_clone) { int backup_route_type; struct usr_avp **backup_list; char *p; /* ... we calculate branch ... */ if (!t_calc_branch(t, branch, request->add_to_branch_s, &request->add_to_branch_len )) { LM_ERR("branch computation failed\n"); goto error; } /* from now on, flag all new lumps with LUMPFLAG_BRANCH flag in order to * be able to remove them later --bogdan */ set_init_lump_flags(LUMPFLAG_BRANCH); /* copy path vector into branch */ if (request->path_vec.len) { t->uac[branch].path_vec.s = shm_realloc(t->uac[branch].path_vec.s, request->path_vec.len+1); if (t->uac[branch].path_vec.s==NULL) { LM_ERR("shm_realloc failed\n"); goto error; } t->uac[branch].path_vec.len = request->path_vec.len; memcpy( t->uac[branch].path_vec.s, request->path_vec.s, request->path_vec.len+1); } /* do the same for the advertised port & address */ if (request->set_global_address.len) { t->uac[branch].adv_address.s = shm_realloc(t->uac[branch].adv_address.s, request->set_global_address.len+1); if (t->uac[branch].adv_address.s==NULL) { LM_ERR("shm_realloc failed for storing the advertised address " "(len=%d)\n",request->set_global_address.len); goto error; } t->uac[branch].adv_address.len = request->set_global_address.len; memcpy( t->uac[branch].adv_address.s, request->set_global_address.s, request->set_global_address.len+1); } if (request->set_global_port.len) { t->uac[branch].adv_port.s = shm_realloc(t->uac[branch].adv_port.s, request->set_global_port.len+1); if (t->uac[branch].adv_port.s==NULL) { LM_ERR("shm_realloc failed for storing the advertised port " "(len=%d)\n",request->set_global_port.len); goto error; } t->uac[branch].adv_port.len = request->set_global_port.len; memcpy( t->uac[branch].adv_port.s, request->set_global_port.s, request->set_global_port.len+1); } /********** run route & callback ************/ /* run branch route, if any; run it before RURI's DNS lookup * to allow to be changed --bogdan */ if (t->on_branch) { /* need to pkg_malloc the dst_uri */ if ( request->dst_uri.s && request->dst_uri.len>0 ) { if ( (p=pkg_malloc(request->dst_uri.len))==0 ) { LM_ERR("no more pkg mem\n"); ser_error=E_OUT_OF_MEM; goto error; } memcpy( p, request->dst_uri.s, request->dst_uri.len); request->dst_uri.s = p; } /* need to pkg_malloc the new_uri */ if ( (p=pkg_malloc(request->new_uri.len))==0 ) { LM_ERR("no more pkg mem\n"); ser_error=E_OUT_OF_MEM; goto error; } memcpy( p, request->new_uri.s, request->new_uri.len); request->new_uri.s = p; request->parsed_uri_ok = 0; /* make a clone of the original body, to restore it later */ if (clone_sip_msg_body( request, NULL, body_clone, 0)!=0) { LM_ERR("faile to clone the body, branch route changes will be" " preserved\n"); } /* make available the avp list from transaction */ backup_list = set_avp_list( &t->user_avps ); /* run branch route */ swap_route_type( backup_route_type, BRANCH_ROUTE); _tm_branch_index = branch; if(run_top_route(sroutes->branch[t->on_branch].a,request)&ACT_FL_DROP){ LM_DBG("dropping branch <%.*s>\n", request->new_uri.len, request->new_uri.s); _tm_branch_index = 0; /* restore the route type */ set_route_type( backup_route_type ); /* restore original avp list */ set_avp_list( backup_list ); goto error; } _tm_branch_index = 0; /* restore the route type */ set_route_type( backup_route_type ); /* restore original avp list */ set_avp_list( backup_list ); } /* run the specific callbacks for this transaction */ run_trans_callbacks( TMCB_REQUEST_FWDED, t, request, 0, -request->REQ_METHOD); /* copy dst_uri into branch (after branch route possible updated it) */ if (request->dst_uri.len) { t->uac[branch].duri.s = shm_realloc(t->uac[branch].duri.s, request->dst_uri.len); if (t->uac[branch].duri.s==NULL) { LM_ERR("shm_realloc failed\n"); goto error; } t->uac[branch].duri.len = request->dst_uri.len; memcpy( t->uac[branch].duri.s,request->dst_uri.s,request->dst_uri.len); } return 0; error: return -1; }
/** * Loads the routing data from the config file given in global * variable config_data and stores it in routing tree rd. * The function mixes code parsing calls with rd structure * completion. * * @param rd Pointer to the route data tree where the routing data * shall be loaded into * * @return 0 means ok, -1 means an error occurred * */ int load_config(struct route_data_t * rd) { FILE * file; int ret_domain, ret_prefix, ret_target, ret_prefix_opts, ret_target_opts; int domain_id, allocated_domain_num = DEFAULT_DOMAIN_NUM; str domain_name, prefix_name, rewrite_host; char domain_buf[CR_MAX_LINE_SIZE], prefix_buf[CR_MAX_LINE_SIZE], rewrite_buf[CR_MAX_LINE_SIZE]; str rewrite_prefix, rewrite_suffix, comment; struct domain_data_t *domain_data = NULL; struct carrier_data_t * tmp_carrier_data; int hash_index, max_targets = 0, strip; double prob; int * backed_up = NULL; int backed_up_size = 0, backup = 0, status; void* p_realloc; int i=0, l, k; domain_name.s = domain_buf; domain_name.len = CR_MAX_LINE_SIZE; prefix_name.s = prefix_buf; prefix_name.len = CR_MAX_LINE_SIZE; rewrite_host.s = rewrite_buf; rewrite_host.len = CR_MAX_LINE_SIZE; /* open configuration file */ if ((file = fopen(config_file, "rb"))==NULL) { LM_ERR("Cannot open source file.\n"); return -1; } rd->carrier_num = 1; rd->first_empty_carrier = 0; rd->domain_num = 0; if ((rd->carriers = shm_malloc(sizeof(struct carrier_data_t *))) == NULL) { SHM_MEM_ERROR; goto errclose; } memset(rd->carriers, 0, sizeof(struct carrier_data_t *)); /* Create carrier map */ if ((rd->carrier_map = shm_malloc(sizeof(struct name_map_t))) == NULL) { SHM_MEM_ERROR; goto errclose; } memset(rd->carrier_map, 0, sizeof(struct name_map_t)); rd->carrier_map[0].id = 1; rd->carrier_map[0].name.len = default_tree.len; rd->carrier_map[0].name.s = shm_malloc(rd->carrier_map[0].name.len); if (rd->carrier_map[0].name.s == NULL) { SHM_MEM_ERROR; goto errclose; } memcpy(rd->carrier_map[0].name.s, default_tree.s, rd->carrier_map[0].name.len); /* Create domain map */ if ((rd->domain_map = shm_malloc(sizeof(struct name_map_t) * allocated_domain_num)) == NULL) { SHM_MEM_ERROR; goto errclose; } memset(rd->domain_map, 0, sizeof(struct name_map_t) * allocated_domain_num); /* Create and insert carrier data structure */ tmp_carrier_data = create_carrier_data(1, &rd->carrier_map[0].name, allocated_domain_num); if (tmp_carrier_data == NULL) { LM_ERR("can't create new carrier\n"); goto errclose; } tmp_carrier_data->domain_num = 0; tmp_carrier_data->id = 1; tmp_carrier_data->name = &(rd->carrier_map[0].name); if (add_carrier_data(rd, tmp_carrier_data) < 0) { LM_ERR("couldn't add carrier data\n"); destroy_carrier_data(tmp_carrier_data); goto errclose; } init_prefix_opts(); init_target_opts(); /* add all routes by parsing the route conf file */ /* while there are domain structures, get name and parse the structure*/ while ((ret_domain = parse_struct_header(file, "domain", &domain_name)) == SUCCESSFUL_PARSING) { domain_id = ++rd->domain_num; tmp_carrier_data->domain_num++; /* (re)allocate memory for a maximum of MAX_DOMAIN_NUM domains rd is not fully allocated from the start as this would require the preparsing of the entire route file */ if ( rd->domain_num > allocated_domain_num){ if (MAX_DOMAIN_NUM <= allocated_domain_num){ LM_ERR("Maximum number of domains reached"); break; } LM_INFO("crt_alloc_size=%d must be increased \n", allocated_domain_num); allocated_domain_num *= 2; if ( ( p_realloc = shm_realloc(rd->domain_map, sizeof(struct name_map_t) * allocated_domain_num) ) == NULL) { SHM_MEM_ERROR; goto errclose; } rd->domain_map = (struct name_map_t *)p_realloc; if (( p_realloc = shm_realloc( rd->carriers[0]->domains, sizeof(struct domain_data_t *) * allocated_domain_num)) == NULL) { SHM_MEM_ERROR; goto errclose; } rd->carriers[0]->domains = (struct domain_data_t **)p_realloc; for (i=0; i<rd->domain_num-1; i++){ rd->carriers[0]->domains[i]->name = &(rd->domain_map[i].name); } }// end of mem (re)allocation for domains /*insert domain in domain map*/ rd->domain_map[domain_id-1].id = domain_id; rd->domain_map[domain_id-1].name.len = domain_name.len; rd->domain_map[domain_id-1].name.s = shm_malloc(rd->domain_map[domain_id-1].name.len); if (rd->domain_map[domain_id-1].name.s == NULL) { SHM_MEM_ERROR; goto errclose; } memcpy(rd->domain_map[domain_id-1].name.s, domain_name.s, rd->domain_map[domain_id-1].name.len); /* create new domain data */ if ((domain_data = create_domain_data(domain_id,&(rd->domain_map[domain_id-1].name))) == NULL) { LM_ERR("could not create new domain data\n"); goto errclose; } if (add_domain_data(tmp_carrier_data, domain_data, domain_id-1) < 0) { LM_ERR("could not add domain data\n"); destroy_domain_data(domain_data); goto errclose; } LM_DBG("added domain %d '%.*s' to carrier %d '%.*s'\n", domain_id, domain_name.len, domain_name.s, tmp_carrier_data->id, tmp_carrier_data->name->len, tmp_carrier_data->name->s); /* while there are prefix structures, get name and parse the structure */ while ((ret_prefix = parse_struct_header(file, "prefix", &prefix_name)) == SUCCESSFUL_PARSING) { reset_prefix_opts(); if (str_strcasecmp(&prefix_name, &CR_EMPTY_PREFIX) == 0) { prefix_name.s[0] = '\0'; prefix_name.len = 0; } /* look for max_targets = value which is described in prefix_options */ if ((ret_prefix_opts = parse_options(file, prefix_options, PO_MAX_IDS, "target")) != SUCCESSFUL_PARSING) { LM_ERR("Error in parsing \n"); goto errclose; } max_targets = prefix_options[PO_MAX_TARGETS].value.int_data; /* look for max_targets target structures */ for ( k = 0; k < max_targets; k++) { /* parse the target header, get name and continue*/ ret_target = parse_struct_header(file, "target", &rewrite_host); if (ret_target != SUCCESSFUL_PARSING) { LM_ERR("Error in parsing \n"); goto errclose; } reset_target_opts(); /* look for the target options: prob, hash index, status, etc*/ ret_target_opts = parse_options(file, target_options, TO_MAX_IDS, "}"); if ( SUCCESSFUL_PARSING == ret_target_opts ){ /* parsing target structure closing bracket*/ parse_struct_stop(file); }else{ LM_ERR("Error in parsing in target options \n"); goto errclose; } /* intermediary variables for more lisibility */ if (str_strcasecmp(&rewrite_host, &CR_EMPTY_PREFIX) == 0) { rewrite_host.s[0] = '\0'; rewrite_host.len = 0; } LM_DBG("loading target %.*s\n", rewrite_host.len, rewrite_host.s); prob = target_options[TO_ID_PROB].value.float_data; strip = target_options[TO_ID_STRIP].value.int_data; rewrite_prefix.s = target_options[TO_ID_REWR_PREFIX].value.string_data.s; rewrite_prefix.len = target_options[TO_ID_REWR_PREFIX].value.string_data.len; rewrite_suffix.s = target_options[TO_ID_REWR_SUFFIX].value.string_data.s; rewrite_suffix.len = target_options[TO_ID_REWR_SUFFIX].value.string_data.len; hash_index = target_options[TO_ID_HASH_INDEX].value.int_data; comment.s = target_options[TO_ID_COMMENT].value.string_data.s; comment.len = target_options[TO_ID_COMMENT].value.string_data.len; status = target_options[TO_ID_STATUS].value.int_data; if ( (backed_up_size = target_options[TO_ID_BACKED_UP].no_elems) > 0){ if ((backed_up = pkg_malloc(sizeof(int) * (backed_up_size + 1))) == NULL) { PKG_MEM_ERROR; goto errclose; } for (l = 0; l < backed_up_size; l++) { backed_up[l] = target_options[TO_ID_BACKED_UP].value.int_list[l]; } backed_up[backed_up_size] = -1; } backup = target_options[TO_ID_BACKUP].value.int_data; LM_DBG("\n Adding route to tree <'%.*s'>: prefix_name:%s\n," " max_targets =%d\n, prob=%f\n, rewr_host=%s\n," " strip=%i\n, rwr_prefix=%s\n, rwr_suff=%s\n," " status=%i\n, hash_index=%i\n, comment=%s \n", domain_data->name->len, domain_data->name->s, prefix_name.s, max_targets, prob, rewrite_host.s, strip, rewrite_prefix.s, rewrite_suffix.s, status, hash_index, comment.s); if (add_route_to_tree(domain_data->tree, &prefix_name, 0, 0, &prefix_name, max_targets, prob, &rewrite_host, strip, &rewrite_prefix, &rewrite_suffix, status, hash_index, backup, backed_up, &comment) < 0) { LM_INFO("Error while adding route\n"); if (backed_up) { pkg_free(backed_up); } goto errclose; } if (backed_up) { pkg_free(backed_up); } backed_up = NULL; } if (k != prefix_options[0].value.int_data ) { LM_ERR("Error in parsing: max_targets =%i, actual targets =%i \n", prefix_options[0].value.int_data, i); goto errclose; } /* parsing prefix structure closing bracket */ if (parse_struct_stop(file) != SUCCESSFUL_PARSING) { LM_ERR("Error in parsing targets, expecting } \n"); goto errclose; } } // END OF PREFIX part /* parsing domain structure closing bracket */ if (parse_struct_stop(file) != SUCCESSFUL_PARSING) { LM_ERR("Error in parsing targets, expecting } \n"); goto errclose; } } if (EOF_REACHED != ret_domain){ LM_ERR("Error appeared while parsing domain header \n"); goto errclose; } LM_INFO("File parsed successfully \n"); fclose(file); return 0; errclose: fclose(file); return -1; }
inline void* Realloc(void* p, uint32 size) { return shm_realloc(m_mem_block, p, size); }
/* 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; }
static int sync_dlg_db_mem(void) { db_res_t * res; db_val_t * values; db_row_t * rows; struct dlg_entry *d_entry; struct dlg_cell *it,*known_dlg,*dlg=NULL; int i, nr_rows,callee_leg_idx,next_id,db_timeout; int no_rows = 10; unsigned int db_caller_cseq,db_callee_cseq,dlg_caller_cseq,dlg_callee_cseq; struct socket_info *caller_sock,*callee_sock; str callid, from_uri, to_uri, from_tag, to_tag; str cseq1,cseq2,contact1,contact2,rroute1,rroute2,mangled_fu,mangled_tu; res = 0; if((nr_rows = select_entire_dialog_table(&res,&no_rows)) < 0) goto error; nr_rows = RES_ROW_N(res); do { LM_DBG("loading information from database for %i dialogs\n", nr_rows); rows = RES_ROWS(res); /* for every row---dialog */ for(i=0; i<nr_rows; i++){ values = ROW_VALUES(rows + i); if (VAL_NULL(values) || VAL_NULL(values+1)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", h_entry_column.len, h_entry_column.s, h_id_column.len, h_id_column.s); continue; } if (VAL_NULL(values+7) || VAL_NULL(values+8)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", start_time_column.len, start_time_column.s, state_column.len, state_column.s); continue; } if ( VAL_INT(values+8) == DLG_STATE_DELETED ) { LM_DBG("dialog already terminated -> skipping\n"); continue; } /*restore the dialog info*/ GET_STR_VALUE(callid, values, 2, 1, 0); GET_STR_VALUE(from_tag, values, 4, 1, 0); GET_STR_VALUE(to_tag, values, 6, 1, 1); /* TODO - check about hash resize ? maybe hash was lowered & we overflow the hash */ known_dlg = 0; d_entry = &(d_table->entries[VAL_INT(values)]); for (it=d_entry->first;it;it=it->next) if (it->callid.len == callid.len && it->legs[DLG_CALLER_LEG].tag.len == from_tag.len && memcmp(it->callid.s,callid.s,callid.len)==0 && memcmp(it->legs[DLG_CALLER_LEG].tag.s,from_tag.s,from_tag.len)==0) { /* callid & ftag match */ callee_leg_idx = callee_idx(it); if (it->legs[callee_leg_idx].tag.len == to_tag.len && memcmp(it->legs[callee_leg_idx].tag.s,to_tag.s,to_tag.len)==0) { /* full dlg match */ known_dlg = it; break; } } if (known_dlg == 0) { LM_DBG("First seen dialog - load all stuff - callid = [%.*s]\n",callid.len,callid.s); GET_STR_VALUE(from_uri, values, 3, 1, 0); GET_STR_VALUE(to_uri, values, 5, 1, 0); caller_sock = create_socket_info(values, 16); callee_sock = create_socket_info(values, 17); if (caller_sock == NULL || callee_sock == NULL) { LM_ERR("Dialog in DB doesn't match any listening sockets"); continue; } /* first time we see this dialog - build it from scratch */ if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){ LM_ERR("failed to build new dialog\n"); goto error; } if(dlg->h_entry != VAL_INT(values)){ LM_ERR("inconsistent hash data in the dialog database: " "you may have restarted opensips using a different " "hash_size: please erase %.*s database and restart\n", dialog_table_name.len, dialog_table_name.s); shm_free(dlg); goto error; } /*link the dialog*/ link_dlg(dlg, 0); dlg->h_id = VAL_INT(values+1); next_id = d_table->entries[dlg->h_entry].next_id; d_table->entries[dlg->h_entry].next_id = (next_id < dlg->h_id) ? (dlg->h_id+1) : next_id; dlg->start_ts = VAL_INT(values+7); dlg->state = VAL_INT(values+8); if (dlg->state==DLG_STATE_CONFIRMED_NA || dlg->state==DLG_STATE_CONFIRMED) { if_update_stat(dlg_enable_stats, active_dlgs, 1); } else if (dlg->state==DLG_STATE_EARLY) { if_update_stat(dlg_enable_stats, early_dlgs, 1); } GET_STR_VALUE(cseq1, values, 10 , 1, 1); GET_STR_VALUE(cseq2, values, 11 , 1, 1); GET_STR_VALUE(rroute1, values, 12, 0, 0); GET_STR_VALUE(rroute2, values, 13, 0, 0); GET_STR_VALUE(contact1, values, 14, 0, 1); GET_STR_VALUE(contact2, values, 15, 0, 1); GET_STR_VALUE(mangled_fu, values, 24,0,1); GET_STR_VALUE(mangled_tu, values, 25,0,1); /* add the 2 legs */ if ( (dlg_add_leg_info( dlg, &from_tag, &rroute1, &contact1, &cseq1, caller_sock,0,0)!=0) || (dlg_add_leg_info( dlg, &to_tag, &rroute2, &contact2, &cseq2, callee_sock,&mangled_fu,&mangled_tu)!=0) ) { LM_ERR("dlg_set_leg_info failed\n"); /* destroy the dialog */ unref_dlg(dlg,1); continue; } dlg->legs_no[DLG_LEG_200OK] = DLG_FIRST_CALLEE_LEG; /* script variables */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, dlg); /* profiles */ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), dlg,0); /* script flags */ if (!VAL_NULL(values+20)) { dlg->user_flags = VAL_INT(values+20); } /* top hiding */ dlg->flags = VAL_INT(values+23); if (dlg_db_mode==DB_MODE_SHUTDOWN) dlg->flags |= DLG_FLAG_NEW; /* calculcate timeout */ dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (dlg->tl.timeout<=(unsigned int)time(0)) dlg->tl.timeout = 0; else dlg->tl.timeout -= (unsigned int)time(0); /* restore the timer values */ if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) { LM_CRIT("Unable to insert dlg %p [%u:%u] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, dlg->legs[DLG_CALLER_LEG].tag.len, dlg->legs[DLG_CALLER_LEG].tag.s, dlg->legs[callee_idx(dlg)].tag.len, ZSW(dlg->legs[callee_idx(dlg)].tag.s)); /* destroy the dialog */ unref_dlg(dlg,1); continue; } /* reference the dialog as kept in the timer list */ ref_dlg(dlg,1); LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout); dlg->lifetime = 0; dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); dlg->legs[callee_idx(dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); if (dlg->flags & DLG_FLAG_PING_CALLER || dlg->flags & DLG_FLAG_PING_CALLEE) { if (0 != insert_ping_timer(dlg)) LM_CRIT("Unable to insert dlg %p into ping timer\n",dlg); else { /* reference dialog as kept in ping timer list */ ref_dlg(dlg,1); } } } else { /* we already saw this dialog before * check which is the newer version */ if (known_dlg->state > VAL_INT(values+8)) { LM_DBG("mem has a newer state - ignore \n"); /* we know a newer version compared to the DB * ignore it */ goto next_dialog; } else if (known_dlg->state == VAL_INT(values+8)) { LM_DBG("mem has same state as DB \n"); /* same state :-( no way to tell which is newer */ /* play nice and store longest timeout, although not always correct*/ db_timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (db_timeout<=(unsigned int)time(0)) db_timeout = 0; else db_timeout -= (unsigned int)time(0); if (known_dlg->tl.timeout < db_timeout) known_dlg->tl.timeout = db_timeout; /* check with is newer cseq for caller leg */ if (!VAL_NULL(values+10)) { cseq1.s = VAL_STR(values+10).s; cseq1.len = strlen(cseq1.s); str2int(&cseq1,&db_caller_cseq); str2int(&known_dlg->legs[DLG_CALLER_LEG].r_cseq,&dlg_caller_cseq); /* Is DB cseq newer ? */ if (db_caller_cseq > dlg_caller_cseq) { if (known_dlg->legs[DLG_CALLER_LEG].r_cseq.len < cseq1.len) { known_dlg->legs[DLG_CALLER_LEG].r_cseq.s = shm_realloc(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.len); if (!known_dlg->legs[DLG_CALLER_LEG].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.s,cseq1.len); known_dlg->legs[DLG_CALLER_LEG].r_cseq.len = cseq1.len; } } else { /* DB has a null cseq - just keep * what we have so far */ ; } /* check with is newer cseq for caller leg */ if (!VAL_NULL(values+11)) { cseq2.s = VAL_STR(values+11).s; cseq2.len = strlen(cseq2.s); callee_leg_idx = callee_idx(known_dlg); str2int(&cseq2,&db_callee_cseq); str2int(&known_dlg->legs[callee_leg_idx].r_cseq,&dlg_callee_cseq); /* Is DB cseq newer ? */ if (db_callee_cseq > dlg_callee_cseq) { if (known_dlg->legs[callee_leg_idx].r_cseq.len < cseq2.len) { known_dlg->legs[callee_leg_idx].r_cseq.s = shm_realloc(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.len); if (!known_dlg->legs[callee_leg_idx].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.s,cseq2.len); known_dlg->legs[callee_leg_idx].r_cseq.len = cseq2.len; } } else { /* DB has a null cseq - just keep * what we have so far */ ; } /* update ping cseqs, whichever is newer */ if (known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq < (unsigned int)(VAL_INT(values+21))) known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); if (known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq < (unsigned int)(VAL_INT(values+22))) known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); /* update script variables * if already found, delete the old ones * and replace with new one */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, known_dlg); /* skip flags - keep what we have - anyway can't tell which is new */ /* profiles - do not insert into a profile * is dlg is already in that profile*/ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), known_dlg,1); } else { /* DB has newer state, just update fields from DB */ LM_DBG("DB has newer state \n"); /* set new state */ known_dlg->state = VAL_INT(values+8); /* update timeout */ known_dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks(); if (known_dlg->tl.timeout<=(unsigned int)time(0)) known_dlg->tl.timeout = 0; else known_dlg->tl.timeout -= (unsigned int)time(0); /* update cseqs */ if (!VAL_NULL(values+10)) { cseq1.s = VAL_STR(values+10).s; cseq1.len = strlen(cseq1.s); if (known_dlg->legs[DLG_CALLER_LEG].r_cseq.len < cseq1.len) { known_dlg->legs[DLG_CALLER_LEG].r_cseq.s = shm_realloc(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.len); if (!known_dlg->legs[DLG_CALLER_LEG].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[DLG_CALLER_LEG].r_cseq.s,cseq1.s,cseq1.len); known_dlg->legs[DLG_CALLER_LEG].r_cseq.len = cseq1.len; } if (!VAL_NULL(values+11)) { cseq2.s = VAL_STR(values+11).s; cseq2.len = strlen(cseq1.s); callee_leg_idx = callee_idx(known_dlg); if (known_dlg->legs[callee_leg_idx].r_cseq.len < cseq2.len) { known_dlg->legs[callee_leg_idx].r_cseq.s = shm_realloc(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.len); if (!known_dlg->legs[callee_leg_idx].r_cseq.s) { LM_ERR("no more shm\n"); goto next_dialog; } } memcpy(known_dlg->legs[callee_leg_idx].r_cseq.s,cseq2.s,cseq2.len); known_dlg->legs[callee_leg_idx].r_cseq.len = cseq2.len; } /* update ping cseqs */ known_dlg->legs[DLG_CALLER_LEG].last_gen_cseq = (unsigned int)(VAL_INT(values+21)); known_dlg->legs[callee_idx(known_dlg)].last_gen_cseq = (unsigned int)(VAL_INT(values+22)); /* update flags */ known_dlg->flags = VAL_INT(values+23); if (dlg_db_mode==DB_MODE_SHUTDOWN) known_dlg->flags |= DLG_FLAG_NEW; /* update script variables * if already found, delete the old one * and replace with new one */ if (!VAL_NULL(values+18)) read_dialog_vars( VAL_STR(values+18).s, VAL_STR(values+18).len, known_dlg); /* profiles - do not insert into a profile * is dlg is already in that profile*/ if (!VAL_NULL(values+19)) read_dialog_profiles( VAL_STR(values+19).s, strlen(VAL_STR(values+19).s), known_dlg,1); } } next_dialog: ; } /* any more data to be fetched ?*/ if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH)) { if (dialog_dbf.fetch_result( dialog_db_handle, &res,no_rows) < 0) { LM_ERR("fetching more rows failed\n"); goto error; } nr_rows = RES_ROW_N(res); } else { nr_rows = 0; } }while (nr_rows>0); return 0; error: return -1; }
/* first time it will called for a CALLER leg - at that time there will be no leg allocated, so automatically CALLER gets the first position, while the CALLEE legs will follow into the array in the same order they came */ int dlg_add_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact,str *cseq, struct socket_info *sock, str *mangled_from,str *mangled_to,str *sdp) { struct dlg_leg* leg,*new_legs; rr_t *head = NULL, *rrp; if ( (dlg->legs_no[DLG_LEGS_ALLOCED]-dlg->legs_no[DLG_LEGS_USED])==0) { new_legs = (struct dlg_leg*)shm_realloc(dlg->legs, (dlg->legs_no[DLG_LEGS_ALLOCED]+2)*sizeof(struct dlg_leg)); if (new_legs==NULL) { LM_ERR("Failed to resize legs array\n"); return -1; } dlg->legs=new_legs; dlg->legs_no[DLG_LEGS_ALLOCED] += 2; memset( dlg->legs+dlg->legs_no[DLG_LEGS_ALLOCED]-2, 0, 2*sizeof(struct dlg_leg)); } leg = &dlg->legs[ dlg->legs_no[DLG_LEGS_USED] ]; leg->tag.s = (char*)shm_malloc(tag->len); leg->r_cseq.s = (char*)shm_malloc( cseq->len ); if ( leg->tag.s==NULL || leg->r_cseq.s==NULL) { LM_ERR("no more shm mem\n"); if (leg->tag.s) shm_free(leg->tag.s); if (leg->r_cseq.s) shm_free(leg->r_cseq.s); return -1; } if (dlg->legs_no[DLG_LEGS_USED] == 0) { /* first leg = caller. also store inv cseq */ leg->inv_cseq.s = (char *)shm_malloc( cseq->len); if (leg->inv_cseq.s == NULL) { LM_ERR("no more shm mem\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); return -1; } } if (contact->len) { /* contact */ leg->contact.s = shm_malloc(rr->len + contact->len); if (leg->contact.s==NULL) { LM_ERR("no more shm mem\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); return -1; } leg->contact.len = contact->len; memcpy( leg->contact.s, contact->s, contact->len); /* rr */ if (rr->len) { leg->route_set.s = leg->contact.s + contact->len; leg->route_set.len = rr->len; memcpy( leg->route_set.s, rr->s, rr->len); if (parse_rr_body(leg->route_set.s,leg->route_set.len,&head) != 0) { LM_ERR("failed parsing route set\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); shm_free(leg->contact.s); return -1; } rrp = head; leg->nr_uris = 0; while (rrp) { leg->route_uris[leg->nr_uris++] = rrp->nameaddr.uri; rrp = rrp->next; } free_rr(&head); } } /* save mangled from URI, if any */ if (mangled_from && mangled_from->s && mangled_from->len) { leg->from_uri.s = shm_malloc(mangled_from->len); if (!leg->from_uri.s) { LM_ERR("no more shm\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); if (leg->contact.s) shm_free(leg->contact.s); return -1; } leg->from_uri.len = mangled_from->len; memcpy(leg->from_uri.s,mangled_from->s,mangled_from->len); } if (mangled_to && mangled_to->s && mangled_to->len) { leg->to_uri.s = shm_malloc(mangled_to->len); if (!leg->to_uri.s) { LM_ERR("no more shm\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); if (leg->contact.s) shm_free(leg->contact.s); if (leg->from_uri.s) shm_free(leg->from_uri.s); return -1; } leg->to_uri.len = mangled_to->len; memcpy(leg->to_uri.s,mangled_to->s,mangled_to->len); } if (sdp && sdp->s && sdp->len) { leg->sdp.s = shm_malloc(sdp->len); if (!leg->sdp.s) { LM_ERR("no more shm\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); if (leg->contact.s) shm_free(leg->contact.s); if (leg->from_uri.s) shm_free(leg->from_uri.s); return -1; } leg->sdp.len = sdp->len; memcpy(leg->sdp.s,sdp->s,sdp->len); } /* tag */ leg->tag.len = tag->len; memcpy( leg->tag.s, tag->s, tag->len); /* socket */ leg->bind_addr = sock; if (dlg->legs_no[DLG_LEGS_USED] == 0) { /* first leg = caller . store inv cseq */ leg->inv_cseq.len = cseq->len; memcpy(leg->inv_cseq.s,cseq->s,cseq->len); /* set cseq for caller to 0 * future requests to the caller leg will update this * needed for proper validation of in-dialog requests * * TM also increases this value by one, if dialog * is terminated from the middle, so 0 is ok*/ leg->r_cseq.len = 1; leg->r_cseq.s[0]='0'; } else { /* cseq */ leg->r_cseq.len = cseq->len; memcpy( leg->r_cseq.s, cseq->s, cseq->len); } /* make leg visible for searchers */ dlg->legs_no[DLG_LEGS_USED]++; LM_DBG("set leg %d for %p: tag=<%.*s> rcseq=<%.*s>\n", dlg->legs_no[DLG_LEGS_USED]-1, dlg, leg->tag.len,leg->tag.s, leg->r_cseq.len,leg->r_cseq.s ); return 0; }
static void *curl_shm_realloc(void *ptr, size_t size) { void *p = shm_realloc(ptr, size); return p; }
int add_set(char * name, char * mode){ int nmode = 0; if(strncmp(mode, "FAILOVER", strlen("FAILOVER")) == 0) nmode = FAILOVER; else if(strncmp(mode, "PARALLEL", strlen("PARALLEL")) == 0) nmode = PARALLEL; else if(strncmp(mode, "ROUND", strlen("ROUND")) == 0) nmode = ROUND; LM_DBG("add set=%s mode=%i\n", name, nmode); if(global){ LM_DBG("realloc\n"); /* realoc set_list */ int i = global->size; global->set_list = (info_set_t *)shm_realloc(global->set_list, (i+1)*sizeof(info_set_t)); if(!global->set_list) MEM_ERR(MEM_SHM); global->size +=1; global->set_list[i].set_name.s = (char *) shm_malloc(strlen(name)*sizeof(char)); global->set_list[i].set_name.len = strlen(name); memcpy(global->set_list[i].set_name.s, name, strlen(name)); /* set mode */ global->set_list[i].set_mode = nmode; global->set_list[i].size = 0 ; }else{ LM_DBG("alloc %p %i\n", global, (int)sizeof(info_global_t)); /* alloc global */ LM_DBG("alloc %p\n", global); global = (info_global_t *) shm_malloc (1 * sizeof(info_global_t)); LM_DBG("alloc %p\n", global); if(!global) MEM_ERR(MEM_SHM); memset(global, 0, 1 * sizeof(info_global_t)); LM_DBG("alloc done\n"); /* alloc set array */ global->set_list = (info_set_t *) shm_malloc (1 * sizeof(info_set_t)); if(!global->set_list) MEM_ERR(MEM_SHM); memset(global->set_list, 0, 1 * sizeof(info_set_t)); /* set array size */ global->size = 1; /* alloc set name */ global->set_list[0].set_name.s = (char *) shm_malloc(strlen(name)*sizeof(char)); global->set_list[0].set_name.len = strlen(name); memcpy(global->set_list[0].set_name.s, name, strlen(name)); /* set mode */ global->set_list[0].set_mode = nmode; /* set size */ global->set_list[0].size=0; } return 0; error: return 1; }
/* first time it will called for a CALLER leg - at that time there will be no leg allocated, so automatically CALLER gets the first position, while the CALLEE legs will follow into the array in the same order they came */ int dlg_add_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact, str *cseq, struct socket_info *sock) { struct dlg_leg* leg; rr_t *head = NULL, *rrp; if ( (dlg->legs_no[DLG_LEGS_ALLOCED]-dlg->legs_no[DLG_LEGS_USED])==0) { dlg->legs_no[DLG_LEGS_ALLOCED] += 2; dlg->legs = (struct dlg_leg*)shm_realloc(dlg->legs, dlg->legs_no[DLG_LEGS_ALLOCED]*sizeof(struct dlg_leg)); if (dlg->legs==NULL) { LM_ERR("Failed to resize legs array\n"); return -1; } memset( dlg->legs+dlg->legs_no[DLG_LEGS_ALLOCED]-2, 0, 2*sizeof(struct dlg_leg)); } leg = &dlg->legs[ dlg->legs_no[DLG_LEGS_USED] ]; leg->tag.s = (char*)shm_malloc(tag->len); leg->r_cseq.s = (char*)shm_malloc( cseq->len ); if ( leg->tag.s==NULL || leg->r_cseq.s==NULL) { LM_ERR("no more shm mem\n"); if (leg->tag.s) shm_free(leg->tag.s); if (leg->r_cseq.s) shm_free(leg->r_cseq.s); return -1; } if (contact->len) { /* contact */ leg->contact.s = shm_malloc(rr->len + contact->len); if (leg->contact.s==NULL) { LM_ERR("no more shm mem\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); return -1; } leg->contact.len = contact->len; memcpy( leg->contact.s, contact->s, contact->len); /* rr */ if (rr->len) { leg->route_set.s = leg->contact.s + contact->len; leg->route_set.len = rr->len; memcpy( leg->route_set.s, rr->s, rr->len); if (parse_rr_body(leg->route_set.s,leg->route_set.len,&head) != 0) { LM_ERR("failed parsing route set\n"); shm_free(leg->tag.s); shm_free(leg->r_cseq.s); shm_free(leg->contact.s); return -1; } rrp = head; leg->nr_uris = 0; while (rrp) { leg->route_uris[leg->nr_uris++] = rrp->nameaddr.uri; rrp = rrp->next; } free_rr(&head); } } /* tag */ leg->tag.len = tag->len; memcpy( leg->tag.s, tag->s, tag->len); /* cseq */ leg->r_cseq.len = cseq->len; memcpy( leg->r_cseq.s, cseq->s, cseq->len); /* socket */ leg->bind_addr = sock; /* make leg visible for searchers */ dlg->legs_no[DLG_LEGS_USED]++; LM_DBG("set leg %d for %p: tag=<%.*s> rcseq=<%.*s>\n", dlg->legs_no[DLG_LEGS_USED]-1, dlg, leg->tag.len,leg->tag.s, leg->r_cseq.len,leg->r_cseq.s ); return 0; }