Exemplo n.º 1
0
Arquivo: t_fwd.c Projeto: OPSF/uClinux
char *print_uac_request( struct cell *t, struct sip_msg *i_req,
                         int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
                         enum sip_protos proto )
{
    char *buf, *shbuf;

    shbuf=0;

    /* ... we calculate branch ... */
    if (!t_calc_branch(t, branch, i_req->add_to_branch_s,
                       &i_req->add_to_branch_len ))
    {
        LOG(L_ERR, "ERROR: print_uac_request: branch computation failed\n");
        goto error01;
    }

    /* ... update uri ... */
    i_req->new_uri=*uri;

    /* run the specific callbacks for this transaction */
    run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0, -i_req->REQ_METHOD);

    /* ... and build it now */
    buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
#ifdef DBG_MSG_QA
    if (buf[*len-1]==0) {
        LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
        abort();
    }
#endif
    if (!buf) {
        LOG(L_ERR, "ERROR: print_uac_request: no pkg_mem\n");
        ser_error=E_OUT_OF_MEM;
        goto error01;
    }
    /*	clean Via's we created now -- they would accumulate for
    	other branches  and for  shmem i_req they would mix up
     	shmem with pkg_mem
    */
    free_via_clen_lump(&i_req->add_rm);

    shbuf=(char *)shm_malloc(*len);
    if (!shbuf) {
        ser_error=E_OUT_OF_MEM;
        LOG(L_ERR, "ERROR: print_uac_request: no shmem\n");
        goto error02;
    }
    memcpy( shbuf, buf, *len );

error02:
    pkg_free( buf );
error01:
    return shbuf;
}
Exemplo n.º 2
0
/**
 * @brief Wrapper function for msg_lump_cloner() with some additional sanity checks
 * @param shm_msg SIP message in shared memory
 * @param pkg_msg SIP message in private memory
 * @return 0 on success, -1 on error
 */
int save_msg_lumps( struct sip_msg *shm_msg, struct sip_msg *pkg_msg)
{
	int ret;
	struct lump* add_rm;
	struct lump* body_lumps;
	struct lump_rpl* reply_lump;
	
	/* make sure that we do not clone the lumps twice */
	if (lumps_are_cloned) {
		LOG(L_DBG, "DEBUG: save_msg_lumps: lumps have been already cloned\n" );
		return 0;
	}
	/* sanity checks */
	if (unlikely(!shm_msg || ((shm_msg->msg_flags & FL_SHM_CLONE)==0))) {
		LOG(L_ERR, "ERROR: save_msg_lumps: BUG, there is no shmem-ized message"
			" (shm_msg=%p)\n", shm_msg);
		return -1;
	}
	if (unlikely(shm_msg->first_line.type!=SIP_REQUEST)) {
		LOG(L_ERR, "ERROR: save_msg_lumps: BUG, the function should be called only for requests\n" );
		return -1;
	}

#ifdef EXTRA_DEBUG
	membar_depends();
	if (shm_msg->add_rm || shm_msg->body_lumps || shm_msg->reply_lump) {
		LOG(L_ERR, "ERROR: save_msg_lumps: BUG, trying to overwrite the already cloned lumps\n");
		return -1;
	}
#endif

	/* needless to clone the lumps for ACK, they will not be used again */
	if (shm_msg->REQ_METHOD == METHOD_ACK)
		return 0;

	/* clean possible previous added vias/clen header or else they would 
	 * get propagated in the failure routes */
	free_via_clen_lump(&pkg_msg->add_rm);

	lumps_are_cloned = 1;
	ret=msg_lump_cloner(pkg_msg, &add_rm, &body_lumps, &reply_lump);
	if (likely(ret==0)){
		/* make sure the lumps are fully written before adding them to
		   shm_msg (in case someone accesses it in the same time) */
		membar_write();
		shm_msg->add_rm = add_rm;
		shm_msg->body_lumps = body_lumps;
		shm_msg->reply_lump = reply_lump;
	}
	return ret<0?-1:0;
}
Exemplo n.º 3
0
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;
}