예제 #1
0
파일: ani_net.cpp 프로젝트: fadan/ani
inline void packet_data_insert_sorted(NetworkState *net, PacketData *queue, u32 max_sequence, u32 sequence, f32 time, i32 size)
{
    if (packet_data_empty(queue))
    {
        packet_data_insert_before(net, queue, sequence, time, size);
    }
    else
    {
        if (!sequence_more_recent(sequence, queue->next->sequence, max_sequence))
        {
            packet_data_insert_before(net, queue->next, sequence, time, size);
        }
        else if (sequence_more_recent(sequence, queue->prev->sequence, max_sequence))
        {
            packet_data_insert_before(net, queue, sequence, time, size);
        }
        else
        {
            for (PacketData *node = queue->next; node != queue; node = node->next)
            {
                assert(node->sequence != sequence);
                if (sequence_more_recent(node->sequence, sequence, max_sequence))
                {
                    packet_data_insert_before(net, node, sequence, time, size);
                    break;
                }
            }
        }
    }
}   
예제 #2
0
		void PacketQueue::insert_sorted( const PacketData & p, unsigned int max_sequence )
		{
			if ( empty() )
			{
				push_back( p );
			}
			else
			{
				if ( !sequence_more_recent( p.sequence, front().sequence, max_sequence ) )
				{
					push_front( p );
				}
				else if ( sequence_more_recent( p.sequence, back().sequence, max_sequence ) )
				{
					push_back( p );
				}
				else
				{
					for ( PacketQueue::iterator itor = begin(); itor != end(); itor++ )
					{
						assert( itor->sequence != p.sequence );
						if ( sequence_more_recent( itor->sequence, p.sequence, max_sequence ) )
						{
							insert( itor, p );
							break;
						}
					}
				}
			}
		}
예제 #3
0
		void ReliabilitySystem::updateQueues()
		{
			const float epsilon = 0.001f;

			while ( sentQueue.size() && sentQueue.front().time > rtt_maximum + epsilon ) {
				sentQueue.pop_front();
			}

			if ( receivedQueue.size() )
			{
				const unsigned int latest_sequence = receivedQueue.back().sequence;
				const unsigned int minimum_sequence = latest_sequence >= 34 ? ( latest_sequence - 34 ) : max_sequence - ( 34 - latest_sequence );
				while ( receivedQueue.size() && !sequence_more_recent( receivedQueue.front().sequence, minimum_sequence, max_sequence ) )
					receivedQueue.pop_front();
			}

			while ( ackedQueue.size() && ackedQueue.front().time > rtt_maximum * 2 - epsilon ) { 
				ackedQueue.pop_front();
			}

			while ( pendingAckQueue.size() && pendingAckQueue.front().time > rtt_maximum + epsilon )
			{
				pendingAckQueue.pop_front();
				lost_packets++;
			}
		}
예제 #4
0
		void ReliabilitySystem::process_ack( unsigned int ack, unsigned int ack_bits, 
								 PacketQueue & pending_ack_queue, PacketQueue & acked_queue, 
								 std::vector<unsigned int> & acks, unsigned int & acked_packets, 
								 float & rtt, unsigned int max_sequence )
		{
			if ( pending_ack_queue.empty() ) {
				return;
			}
				
			PacketQueue::iterator itor = pending_ack_queue.begin();
			while ( itor != pending_ack_queue.end() )
			{
				bool acked = false;
				
				if ( itor->sequence == ack )
				{
					acked = true;
				}
				else if ( !sequence_more_recent( itor->sequence, ack, max_sequence ) )
				{
					int bit_index = bit_index_for_sequence( itor->sequence, ack, max_sequence );
					if ( bit_index <= 31 ) { 
						acked = ( ack_bits >> bit_index ) & 1;
					}
				}
예제 #5
0
void ReliabilitySystem::process_ack(unsigned int ack, unsigned int ack_bits,
							PacketQueue & pending_ack_queue, PacketQueue & acked_queue,
							std::vector<unsigned int> & acks, unsigned int & acked_packets,
							float & rtt, unsigned int max_sequence)
{
	if (pending_ack_queue.empty())
		return;

	PacketQueue::iterator itor = pending_ack_queue.begin();
	while (itor != pending_ack_queue.end()) {
		bool acked = false;

		if (itor->sequence == ack) {
			acked = true;
		} else if (!sequence_more_recent(itor->sequence, ack, max_sequence)) {
			int bit_index = bit_index_for_sequence(itor->sequence, ack, max_sequence);
			if (bit_index <= 31)
				acked = (ack_bits >> bit_index) & 1;
		}

		if (acked) {
			rtt += (itor->time - rtt) * 0.1f;

			acked_queue.insert_sorted(*itor, max_sequence);
			acks.push_back(itor->sequence);
			acked_packets++;
			itor = pending_ack_queue.erase(itor);
		} else {
			++itor;
		}
	}
예제 #6
0
void PacketQueue::verify_sorted( quint32 max_sequence ){
	PacketQueue::iterator prev = end();
	for ( PacketQueue::iterator itor = begin(); itor != end(); itor++ ){
		assert( itor->sequence <= max_sequence );
		if ( prev != end() ){
			assert( sequence_more_recent( itor->sequence, prev->sequence, max_sequence ) );
			prev = itor;
		}
	}
}
예제 #7
0
파일: ani_net.cpp 프로젝트: fadan/ani
inline void packet_data_verify_sorted(PacketData *queue, u32 max_sequence)
{
    for (PacketData *node = queue->next; node != queue; node = node->next)
    {
        assert(node->sequence <= max_sequence);
        if (node->prev != queue)
        {
            assert(sequence_more_recent(node->sequence, node->prev->sequence, max_sequence));
        }
    }
}
예제 #8
0
unsigned int ReliabilitySystem::generate_ack_bits(unsigned int ack, const PacketQueue & received_queue, unsigned int max_sequence) {
	unsigned int ack_bits = 0;
	for (PacketQueue::const_iterator itor = received_queue.begin(); itor != received_queue.end(); itor++) {
		if (itor->sequence == ack || sequence_more_recent(itor->sequence, ack, max_sequence))
			break;
		int bit_index = bit_index_for_sequence(itor->sequence, ack, max_sequence);
		if (bit_index <= 31)
			ack_bits |= 1 << bit_index;
	}
	return ack_bits;
}
예제 #9
0
void ReliabilitySystem::PacketReceived(unsigned int sequence, int size) {
	FunctionLock lock(thisLock);
	recv_packets++;
	if (receivedQueue.exists(sequence))
		return;
	PacketData data;
	data.sequence = sequence;
	data.time = 0.0f;
	data.size = size;
	receivedQueue.push_back(data);
	if (sequence_more_recent(sequence, remote_sequence, max_sequence))
		remote_sequence = sequence;
}
예제 #10
0
        // TODOCM maybe change from uint8 to bigger value for bigger chains
        static int16_t sequence_difference(uint8_t s1, uint8_t s2, unsigned int max)
        {
            // If s1 is larger and the difference is less then half
            // meaning if they're not wrapped, the differnce should be less then half for it to be more recent
            // or
            //  If s2 is the larger one, and their difference is larger then half
            // meaning if they're wrapped, the difference should be more then half for it to be wrapped

            if(s1 > s2)
            {
                if(sequence_more_recent(s1, s2, max))
                {
                    return s1 - s2;
                }
                else
                {
                    return -(max - s1 + s2 + 1);
                }
            }
            else if(s2 > s1) // TODOCM check if this really is right
            {
                if(sequence_more_recent(s1, s2, max))
                {
                    return max + 1 - s2 + s1;
                }
                else
                {
                    return s1 - s2;
                }
            }
            else
            {
                // std::cout << "Snapshot sequence is same, something is wrong" << std::endl; // TODOCM remove maybe
                return 0;
            }
        }
예제 #11
0
int ReliabilitySystem::bit_index_for_sequence(unsigned int sequence, unsigned int ack, unsigned int max_sequence) {
	assert(sequence != ack);
	assert(!sequence_more_recent(sequence, ack, max_sequence));
	if (sequence > ack) {
		//TODO: This fails because too many physics updates per tick
		//if (ack >= 33)
		//	assert(ack < 33);
		if (max_sequence < sequence)
			assert(max_sequence >= sequence);
 		return ack + (max_sequence - sequence);
	} else {
		assert(ack >= 1);
		assert(sequence <= ack - 1);
 		return ack - 1 - sequence;
	}
}
예제 #12
0
		int ReliabilitySystem::bit_index_for_sequence( unsigned int sequence, unsigned int ack, unsigned int max_sequence )
		{
			assert( sequence != ack );
			assert( !sequence_more_recent( sequence, ack, max_sequence ) );
			if ( sequence > ack )
			{
				assert( ack < 33 );
				assert( max_sequence >= sequence );
 				return ack + ( max_sequence - sequence );
			}
			else
			{
				assert( ack >= 1 );
				assert( sequence <= ack - 1 );
 				return ack - 1 - sequence;
			}
		}
예제 #13
0
파일: ani_net.cpp 프로젝트: fadan/ani
static u32 generate_ack_bits(u32 ack, PacketData *recv_queue, u32 max_sequence)
{
    u32 ack_bits = 0;
    for (PacketData *node = recv_queue->next; node != recv_queue; node = node->next)
    {
        if (node->sequence == ack || sequence_more_recent(node->sequence, ack, max_sequence))
        {
            break;
        }

        i32 bit_index = bit_index_for_sequence(node->sequence, ack, max_sequence);        
        if (bit_index <= 31)
        {
            ack_bits |= 1 << bit_index;
        }
    }
    return ack_bits;
}
예제 #14
0
파일: ani_net.cpp 프로젝트: fadan/ani
static void process_ack(NetworkState *net, u32 ack, u32 ack_bits)
{
    if (!packet_data_empty(net->pending_ack_queue))
    {
        PacketData *node = net->pending_ack_queue->next;
        while (node != net->pending_ack_queue)
        {
            b32 acked = false;
            if (node->sequence == ack)
            {
                acked = true;
            }
            else if (!sequence_more_recent(node->sequence, ack, net->max_sequence))
            {
                i32 bit_index = bit_index_for_sequence(node->sequence, ack, net->max_sequence);
                if (bit_index <= 31)
                {
                    acked = (ack_bits >> bit_index) & 1;
                }
            }
예제 #15
0
파일: ani_net.cpp 프로젝트: fadan/ani
static i32 bit_index_for_sequence(u32 sequence, u32 ack, u32 max_sequence)
{
    assert(sequence != ack);
    assert(!sequence_more_recent(sequence, ack, max_sequence));

    i32 result = 0;
    if (sequence > ack)
    {
        assert(ack < 33);
        assert(max_sequence >= sequence);

        result = ack + (max_sequence - sequence);
    }
    else
    {
        assert(ack >= 1);
        assert(sequence  <= (ack - 1));

        result = ack - 1 - sequence;
    }
    return result;
}
예제 #16
0
파일: ani_net.cpp 프로젝트: fadan/ani
static void update_connection(NetworkState *net, Connection *connection, f32 dt)
{
    // NOTE(dan): clear acks array
    net->num_acks = 0;

    // NOTE(dan): update connection
    {
        connection->timeout_accum += dt;
        if (connection->timeout_accum > connection->timeout_sec)
        {
            if (connection->state == ConnectionState_Connecting ||
                connection->state == ConnectionState_Connected)
            {
                connection->state = ConnectionState_ConnectionFailed;
            }
        }
    }

    // NOTE(dan): advance queue time
    {
        for (PacketData *node = net->sent_queue->next; node != net->sent_queue; node = node->next)
        {
            node->time += dt;
        }
        for (PacketData *node = net->recv_queue->next; node != net->recv_queue; node = node->next)
        {
            node->time += dt;
        }
        for (PacketData *node = net->pending_ack_queue->next; node != net->pending_ack_queue; node = node->next)
        {
            node->time += dt;
        }
        for (PacketData *node = net->acked_queue->next; node != net->acked_queue; node = node->next)
        {
            node->time += dt;
        }
    }

    // NOTE(dan): update queues
    {
        f32 epsilon = 0.001f;
        while (!packet_data_empty(net->sent_queue) && (net->sent_queue->next->time > (net->max_rtt + epsilon)))
        {
            packet_data_delete_node(net, net->sent_queue->next);
        }

        if (!packet_data_empty(net->recv_queue))
        {
            u32 latest_sequence = net->recv_queue->prev->sequence;
            u32 min_sequence = latest_sequence >= 34 ? (latest_sequence - 34) : net->max_sequence - (34 - latest_sequence);

            while (!packet_data_empty(net->recv_queue) && !sequence_more_recent(net->recv_queue->next->sequence, min_sequence, net->max_sequence))
            {
                packet_data_delete_node(net, net->recv_queue->next);
            }
        }

        while (!packet_data_empty(net->acked_queue) && (net->acked_queue->next->time > (net->max_rtt * 2 - epsilon)))
        {
            packet_data_delete_node(net, net->acked_queue->next);
        }

        while (!packet_data_empty(net->pending_ack_queue) && (net->pending_ack_queue->next->time > (net->max_rtt + epsilon)))
        {
            packet_data_delete_node(net, net->pending_ack_queue->next);
            ++net->lost_packets;
        }
    }

    // NOTE(dan): update stats
    {
        i32 sent_bytes_per_sec = 0;
        i32 acked_packets_per_sec = 0;
        i32 acked_bytes_per_sec = 0;

        for (PacketData *node = net->sent_queue->next; node != net->sent_queue; node = node->next)
        {
            sent_bytes_per_sec += node->size;
        }

        for (PacketData *node = net->acked_queue->next; node != net->acked_queue; node = node->next)
        {
            if (node->time >= net->max_rtt)
            {
                ++acked_packets_per_sec;
                acked_bytes_per_sec += node->size;
            }
        }

        sent_bytes_per_sec = (i32)(sent_bytes_per_sec / net->max_rtt);
        acked_bytes_per_sec = (i32)(acked_bytes_per_sec / net->max_rtt);

        net->sent_bandwidth = sent_bytes_per_sec * (8 / 1000.0f);
        net->acked_bandwidth = acked_bytes_per_sec * (8 / 1000.0f);
    }

    // NOTE(dan): validate
    #if INTERNAL_BUILD
    {
        packet_data_verify_sorted(net->sent_queue, net->max_sequence);
        // packet_data_verify_sorted(net->recv_queue, net->max_sequence);
        packet_data_verify_sorted(net->pending_ack_queue, net->max_sequence);
        packet_data_verify_sorted(net->acked_queue, net->max_sequence);
    }
    #endif
}
예제 #17
0
        void NetworkEventReceiver::ReadEvents(NetworkStreamer& p_streamer, uint32_t p_bufferSize, uint32_t& op_BytesRead)
        {
            // Get header size
            uint32_t t_headerSize = sizeof(uint8_t) * 2;

            // Check how many bytes we have left to write
            uint32_t bytesLeftToRead = p_bufferSize - op_BytesRead;

            // Check if we can read headers
            if(bytesLeftToRead < t_headerSize)
            {
                return;
            }

            // Read number of sequences packets
            uint8_t NumOfSequencesLeft = p_streamer.ReadUnsignedInt8();
            bytesLeftToRead -= sizeof(uint8_t);
            op_BytesRead += sizeof(uint8_t);

            // Read starting sequence
            uint8_t CurrentSequence = p_streamer.ReadUnsignedInt8();
            bytesLeftToRead -= sizeof(uint8_t);
            op_BytesRead += sizeof(uint8_t);

            // While we still got sequences to read, and already have them, we skip to use
            while(NumOfSequencesLeft && sequence_more_recent(m_currentSequence, CurrentSequence, 255))
            {
                // Increment how many we read, and how many that are left
                CurrentSequence++;
                NumOfSequencesLeft--;

                uint32_t t_bitsRead = 0;

                // If we don't have enough memory to read next line
                if(bytesLeftToRead < sizeof(uint8_t))
                {
                    return;
                }

                // Interpet events and throw
                InterpetEventAndThrow(p_streamer, t_bitsRead);

                // Get full bytes read
                uint32_t t_FullBytesRead = ceil((float)t_bitsRead / 8.0f);
                bytesLeftToRead -= t_FullBytesRead;
                op_BytesRead += t_FullBytesRead;

                // Set read point
                p_streamer.SetReadWritePosition(op_BytesRead);
            }

            // Increment by how many we should read, could move this for each we read instead
            m_currentSequence += NumOfSequencesLeft;

            // While we still have sequences left to read
            while(NumOfSequencesLeft)
            {
                uint32_t t_bitsRead = 0;

                // If we don't have enough memory to read next line
                if(bytesLeftToRead < sizeof(uint8_t))
                {
                    return;
                }

                // Interpet events and save
                InterpetEventAndQueue(p_streamer, t_bitsRead);

                // Get full bytes read
                uint32_t t_FullBytesRead = ceil((float)t_bitsRead / 8.0f);
                bytesLeftToRead -= t_FullBytesRead;
                op_BytesRead += t_FullBytesRead;

                // Set read point
                p_streamer.SetReadWritePosition(op_BytesRead);

                // Decrement counter
                NumOfSequencesLeft--;
            }
        }