Esempio n. 1
0
/**RFC3320-Setction_8.4.  Byte copying
From UDVM to UDVM
*/
int tcomp_udvm_bytecopy_self(tcomp_udvm_t *udvm, uint32_t *destination, uint32_t source, uint32_t tsk_size_tocopy)
{
	uint32_t byte_copy_left, byte_copy_right;
	//if (*destination == TCOMP_UDVM_GET_SIZE() || source == TCOMP_UDVM_GET_SIZE())
	if (*destination >= TCOMP_UDVM_GET_SIZE() || source >= TCOMP_UDVM_GET_SIZE())
	{
		/* SEGFAULT */
		tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT);
		return 0;
	}

	/*
	* The string of bytes is copied in ascending order of memory address,
	* respecting the bounds set by byte_copy_left and byte_copy_right.
	*/	
	byte_copy_left = TCOMP_UDVM_GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_LEFT_INDEX);
	byte_copy_right = TCOMP_UDVM_GET_2BYTES_VAL(TCOMP_UDVM_HEADER_BYTE_COPY_RIGHT_INDEX);
	
	// string of bytes is copied one byte at a time
	while((tsk_size_tocopy--))
	{
		*TCOMP_UDVM_GET_BUFFER_AT((*destination)++) = *TCOMP_UDVM_GET_BUFFER_AT(source++);
		
		*destination = (*destination == byte_copy_right)? byte_copy_left : *destination;
		source = (source == byte_copy_right)? byte_copy_left : source;
	}

	return 1;
}
Esempio n. 2
0
//========================================================
//	UDVM machine definition
//
static tsk_object_t* tcomp_udvm_ctor(tsk_object_t * self, va_list * app)
{
	tcomp_udvm_t *udvm = self;
	if(udvm){
		/* RFC 3320 - 7.  SigComp Message Format */
		udvm->sigCompMessage = va_arg(*app, tcomp_message_t *);
		udvm->stateHandler = va_arg(*app, tcomp_statehandler_t *);
		udvm->lpResult = va_arg(*app, tcomp_result_t *);
		
		udvm->isOK = tsk_true;
		udvm->maximum_UDVM_cycles = 0; /* RFC 3320 subclause 8.6 */
		udvm->consumed_cycles = 0;
		udvm->memory = tcomp_buffer_create_null();

		/* Alloc UDVM memory */
		if(udvm->sigCompMessage->stream_based){
			/*
			* If the transport is stream-based however, then a fixed-size input buffer is required to accommodate the stream, independently of the
			* size of each SigComp message. So, for simplicity, the UDVM memory size is set to (decompression_memory_size / 2).
			*/

			tcomp_buffer_allocBuff(udvm->memory, udvm->stateHandler->sigcomp_parameters->dmsValue/2);
		}
		else{
			/*
			* If the transport is message-based then sufficient memory must be available
			* to buffer the entire SigComp message before it is passed to the UDVM. So if the message is n bytes long, then the UDVM memory size is set
			* to (decompression_memory_size - n), up to a maximum of 65536 bytes.
			*/
			tcomp_buffer_allocBuff(udvm->memory, (udvm->stateHandler->sigcomp_parameters->dmsValue-udvm->sigCompMessage->totalSize));
		}

		/*
		* Has feedback with my state id?
		*/
		if(tcomp_buffer_getSize(udvm->sigCompMessage->ret_feedback_buffer)){
			tsk_size_t size = tcomp_buffer_getSize(udvm->sigCompMessage->ret_feedback_buffer);
			tcomp_buffer_allocBuff(udvm->lpResult->ret_feedback, size);
			memcpy(tcomp_buffer_getBuffer(udvm->lpResult->ret_feedback), tcomp_buffer_getBuffer(udvm->sigCompMessage->ret_feedback_buffer), size);
		}
		
		/*
		*	Has state?
		*/
		if(tcomp_buffer_getSize(udvm->sigCompMessage->stateId)){
			/* Find the provided state */
			tcomp_state_t* lpState = NULL;
			uint16_t match_count = tcomp_statehandler_findState(udvm->stateHandler, udvm->sigCompMessage->stateId, &lpState);
			if( (!match_count || match_count>1 || !lpState)
				|| (lpState->minimum_access_length > tcomp_buffer_getSize(udvm->sigCompMessage->stateId))
				|| ((tsk_size_t)(lpState->address + lpState->length) > TCOMP_UDVM_GET_SIZE()) )
			{
				tcomp_udvm_createNackInfo(udvm, NACK_STATE_NOT_FOUND, udvm->sigCompMessage->stateId, 0);
				udvm->isOK = tsk_false;
				return self;
			}
			//this->sigCompMessage->stateId.print();//FIXME
			/*
			* Copy bytecodes to UDVM memory
			*/
			if( (tsk_size_t)(lpState->address + lpState->length) >= TCOMP_UDVM_GET_SIZE() ){
				tcomp_udvm_createNackInfo2(udvm, NACK_SEGFAULT);
				udvm->isOK = tsk_false;
				return self;
			}
			memcpy( TCOMP_UDVM_GET_BUFFER_AT(lpState->address), 
				tcomp_buffer_getBuffer(lpState->value), 
				tcomp_buffer_getSize(lpState->value) );
			
			//RFC 3320 - 7.2.  Accessing Stored State (Useful values)
			TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_PARTIAL_STATE_ID_LENGTH_INDEX, tcomp_buffer_getSize(udvm->sigCompMessage->stateId));
			TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_STATE_LENGTH_INDEX, tcomp_buffer_getSize(lpState->value));
			
			udvm->executionPointer = lpState->instruction;
		}
		else // DON'T HAVE STATE
		{
			/*
			* Copy bytecodes to UDVM memory
			*/
			tsk_size_t bytecodes_destination = udvm->sigCompMessage->bytecodes_destination;
			if( (bytecodes_destination + tcomp_buffer_getSize(udvm->sigCompMessage->uploaded_UDVM_buffer)) >= TCOMP_UDVM_GET_SIZE() ){
				tcomp_udvm_createNackInfo2(udvm, NACK_BYTECODES_TOO_LARGE);
				udvm->isOK = tsk_false;
				return self;
			}
			memcpy( TCOMP_UDVM_GET_BUFFER_AT(bytecodes_destination),
				tcomp_buffer_getBuffer(udvm->sigCompMessage->uploaded_UDVM_buffer),
				tcomp_buffer_getSize(udvm->sigCompMessage->uploaded_UDVM_buffer));

			// Set pointer indicating execution index
			udvm->executionPointer = bytecodes_destination;
		}

		/* RFC 3320-Section_8.6.  UDVM Cycles
		/*
		* To ensure that a SigComp message cannot consume excessive processing
		* resources, SigComp limits the number of "UDVM cycles" allocated to
		* each message.  The number of available UDVM cycles is initialized to
		* 1000 plus the number of bits in the SigComp header (as described in
		* Section 7); this sum is then multiplied by cycles_per_bit.
		*/
		/*maximum_UDVM_cycles = (8 * n + 1000) * cycles_per_bit*///FIXME:header_size
		udvm->maximum_UDVM_cycles = ( (8 * udvm->sigCompMessage->header_size + 1000)* udvm->stateHandler->sigcomp_parameters->cpbValue );
		
		//
		//	RFC 3320 - 7.2.  Useful values
		//
		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_UDVM_MEMORY_SIZE_INDEX, TCOMP_UDVM_GET_SIZE());
		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_CYCLES_PER_BIT_INDEX, udvm->stateHandler->sigcomp_parameters->cpbValue);
		TCOMP_UDVM_SET_2BYTES_VAL(TCOMP_UDVM_HEADER_SIGCOMP_VERSION_INDEX, udvm->stateHandler->sigcomp_parameters->SigComp_version);
		memset(TCOMP_UDVM_GET_BUFFER_AT(TCOMP_UDVM_HEADER_RESERVED_INDEX), 0, TCOMP_UDVM_HEADER_RESERVED_SIZE);
	}
	else{