struct cell* build_cell( struct sip_msg* p_msg ) { struct cell* new_cell; unsigned int i; unsigned int myrand; int size; char *c; struct ua_client *uac; /* avoid 'unitialized var use' warning */ myrand=0; /* allocs a new cell */ new_cell = (struct cell*)shm_malloc( sizeof( struct cell ) ); if ( !new_cell ) { ser_error=E_OUT_OF_MEM; return NULL; } /* filling with 0 */ memset( new_cell, 0, sizeof( struct cell ) ); /* UAS */ #ifdef EXTRA_DEBUG new_cell->uas.response.retr_timer.tg=TG_RT; new_cell->uas.response.fr_timer.tg=TG_FR; #endif new_cell->uas.response.fr_timer.payload = new_cell->uas.response.retr_timer.payload = &(new_cell->uas.response); new_cell->uas.response.my_T=new_cell; /* bogdan - debug */ /*fprintf(stderr,"before clone VIA |%.*s|\n",via_len(p_msg->via1), via_s(p_msg->via1,p_msg));*/ /* enter callback, which may potentially want to parse some stuff, before the request is shmem-ized */ if (p_msg) callback_event(TMCB_REQUEST_IN, new_cell, p_msg, p_msg->REQ_METHOD ); if (p_msg) { new_cell->uas.request = sip_msg_cloner(p_msg); if (!new_cell->uas.request) goto error; } /* new_cell->uas.to_tag = &( get_to(new_cell->uas.request)->tag_value ); */ new_cell->uas.response.my_T = new_cell; /* UAC */ for(i=0;i<MAX_BRANCHES;i++) { uac=&new_cell->uac[i]; uac->request.my_T = new_cell; uac->request.branch = i; #ifdef EXTRA_DEBUG uac->request.fr_timer.tg = TG_FR; uac->request.retr_timer.tg = TG_RT; #endif uac->request.retr_timer.payload = uac->request.fr_timer.payload = &uac->request; uac->local_cancel=uac->request; } /* global data for transaction */ if (p_msg) { new_cell->hash_index = p_msg->hash_index; } else { /* note: unsatisfactory if RAND_MAX < TABLE_ENTRIES */ myrand = rand(); new_cell->hash_index = myrand % TABLE_ENTRIES ; } new_cell->wait_tl.payload = new_cell; new_cell->dele_tl.payload = new_cell; new_cell->relaied_reply_branch = -1; /* new_cell->T_canceled = T_UNDEFINED; */ #ifdef EXTRA_DEBUG new_cell->wait_tl.tg=TG_WT; new_cell->dele_tl.tg=TG_DEL; #endif if (!syn_branch) { if (p_msg) { /* char value of a proxied transaction is calculated out of header-fileds forming transaction key */ char_msg_val( p_msg, new_cell->md5 ); } else { /* char value for a UAC transaction is created randomly -- UAC is an originating stateful element which cannot be refreshed, so the value can be anything */ /* HACK : not long enough */ c=new_cell->md5; size=MD5_LEN; memset(c, '0', size ); int2reverse_hex( &c, &size, myrand ); } } init_cell_lock( new_cell ); return new_cell; error: shm_free(new_cell); return NULL; }
struct cell* build_cell( struct sip_msg* p_msg ) { struct cell* new_cell; int sip_msg_len; avp_list_t* old; /* allocs a new cell */ new_cell = (struct cell*)shm_malloc( sizeof( struct cell ) ); if ( !new_cell ) { ser_error=E_OUT_OF_MEM; return NULL; } /* filling with 0 */ memset( new_cell, 0, sizeof( struct cell ) ); /* UAS */ new_cell->uas.response.my_T=new_cell; init_rb_timers(&new_cell->uas.response); /* timers */ init_cell_timers(new_cell); old = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &new_cell->uri_avps_from ); new_cell->uri_avps_from = *old; *old = 0; old = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &new_cell->uri_avps_to ); new_cell->uri_avps_to = *old; *old = 0; old = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &new_cell->user_avps_from ); new_cell->user_avps_from = *old; *old = 0; old = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &new_cell->user_avps_to ); new_cell->user_avps_to = *old; *old = 0; /* We can just store pointer to domain avps in the transaction context, * because they are read-only */ new_cell->domain_avps_from = get_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN); new_cell->domain_avps_to = get_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN); /* enter callback, which may potentially want to parse some stuff, * before the request is shmem-ized */ if ( p_msg && has_reqin_tmcbs() ) run_reqin_callbacks( new_cell, p_msg, p_msg->REQ_METHOD); if (p_msg) { /* clean possible previous added vias/clen header or else they would * get propagated in the failure routes */ free_via_clen_lump(&p_msg->add_rm); new_cell->uas.request = sip_msg_cloner(p_msg,&sip_msg_len); if (!new_cell->uas.request) goto error; new_cell->uas.end_request=((char*)new_cell->uas.request)+sip_msg_len; } /* UAC */ init_branches(new_cell); new_cell->relayed_reply_branch = -1; /* new_cell->T_canceled = T_UNDEFINED; */ init_synonym_id(new_cell); init_cell_lock( new_cell ); return new_cell; error: destroy_avp_list(&new_cell->user_avps_from); destroy_avp_list(&new_cell->user_avps_to); destroy_avp_list(&new_cell->uri_avps_from); destroy_avp_list(&new_cell->uri_avps_to); shm_free(new_cell); /* unlink transaction AVP list and link back the global AVP list (bogdan)*/ reset_avps(); return NULL; }