Пример #1
0
		internal void AddPacket(RUDPIngoingPacket packet)
		{
			lock (_lock)
			{
				if (packet.PacketId < 0)
				{
					_list.AddLast(packet);
					return;
				}

				LinkedListNode<RUDPIngoingPacket> node = _list.Last;
				while (node != null && (node.Value.PacketId < 0 || packet.PacketId < node.Value.PacketId))
					node = node.Previous;

				if (node == null)
				{
					_list.AddFirst(packet);
					return;
				}

				// If duplicated packet -> drop
				if (packet.PacketId == node.Value.PacketId)
					return;

				// Add
				_list.AddAfter(node, packet);
			}
		}
Пример #2
0
 internal void OnReceive(RUDPIngoingPacket packet)
 {
     if (packet != null)
     {
         Interlocked.Exchange(ref _rwnd, _rwnd + packet.Payload.Length);
     }
 }
Пример #3
0
        internal void AddPacket(RUDPIngoingPacket packet)
        {
            lock (_lock)
            {
                if (packet.PacketId < 0)
                {
                    _list.AddLast(packet);
                    return;
                }

                LinkedListNode <RUDPIngoingPacket> node = _list.Last;
                while (node != null && (node.Value.PacketId < 0 || packet.PacketId < node.Value.PacketId))
                {
                    node = node.Previous;
                }

                if (node == null)
                {
                    _list.AddFirst(packet);
                    return;
                }

                // If duplicated packet -> drop
                if (packet.PacketId == node.Value.PacketId)
                {
                    return;
                }

                // Add
                _list.AddAfter(node, packet);
            }
        }
Пример #4
0
        internal void AddPacket(RUDPIngoingPacket packet)
        {
            if (packet.PacketId < 0)
            {
                _lock.EnterWriteLock();
                _list.AddLast(packet);
                _lock.ExitWriteLock();
                return;
            }

            _lock.EnterUpgradeableReadLock();

            try
            {
                LinkedListNode <RUDPIngoingPacket> node = _list.Last;
                while (node != null && (node.Value.PacketId < 0 || packet.PacketId < node.Value.PacketId))
                {
                    node = node.Previous;
                }

                if (node == null)
                {
                    _lock.EnterWriteLock();
                    _list.AddFirst(packet);
                    _lock.ExitWriteLock();                     // Needed ?
                    return;
                }

                // If duplicated packet -> drop
                if (packet.PacketId == node.Value.PacketId)
                {
                    return;
                }

                // Add
                _lock.EnterWriteLock();
                _list.AddAfter(node, packet);
                _lock.ExitWriteLock();                 // Needed ?
            }
            finally
            {
                _lock.ExitUpgradeableReadLock();
            }
        }
Пример #5
0
		internal void AddPacket(RUDPIngoingPacket packet)
		{
			if (packet.PacketId < 0)
			{
				_lock.EnterWriteLock();
				_list.AddLast(packet);
				_lock.ExitWriteLock();
				return;
			}

			_lock.EnterUpgradeableReadLock();

			try
			{
				LinkedListNode<RUDPIngoingPacket> node = _list.Last;
				while (node != null && (node.Value.PacketId < 0 || packet.PacketId < node.Value.PacketId))
					node = node.Previous;

				if (node == null)
				{
					_lock.EnterWriteLock();
					_list.AddFirst(packet);
					_lock.ExitWriteLock(); // Needed ?
					return;
				}

				// If duplicated packet -> drop
				if (packet.PacketId == node.Value.PacketId)
					return;

				// Add
				_lock.EnterWriteLock();
				_list.AddAfter(node, packet);
				_lock.ExitWriteLock(); // Needed ?
			}
			finally
			{
				_lock.ExitUpgradeableReadLock();
			}
		}
Пример #6
0
		internal void OnReceiveProcessed(RUDPIngoingPacket packet)
		{
			Interlocked.Exchange(ref _rwnd, _rwnd - packet.Payload.Length);
		}
Пример #7
0
		internal void OnReceive(RUDPIngoingPacket packet)
		{
			if (packet != null)
				Interlocked.Exchange(ref _rwnd, _rwnd + packet.Payload.Length);
		}
Пример #8
0
		private static void HandlePacket(PhysicalSocket physical,
										IPEndPoint sender,
										RUDPPacketChannel channel,
										int packetId,
										int advertisedWindowSize,
										SACKSlot slot1, SACKSlot slot2, SACKSlot slot3, SACKSlot slot4,
										byte[] payload)
		{
			RUDPSocket rudp = null;

			//---- PING
			if (channel == RUDPPacketChannel.Ping || channel == RUDPPacketChannel.PingRendezVous)
			{
				rudp = HandlePing(physical, sender, packetId, channel);

				// Do not handle this message
				if (rudp == null)
					return;
			}

			//---- Search the socket
			if (rudp == null)
			{
				physical._connectedRDUPsLock.EnterReadLock();
				physical._connectedRDUPs.TryGetValue(sender, out rudp);
				physical._connectedRDUPsLock.ExitReadLock();
			}

			//---- Direct send of ACK, because socket can be shutdowned and removed
			if (channel == RUDPPacketChannel.TearDown)
			{
				byte[] packetPayload = MakePacketPayload(rudp, -1, RUDPPacketChannel.ACK, new SACKSlot(packetId, packetId), null, null, null, null, 0, 0);
				SocketSendACK(rudp, physical, sender, packetPayload);
				PayloadManager.Deallocate(RUDPPacketChannel.ACK, packetPayload);
			}

			//---- Released socket
			if (rudp == null)
				return;

#if CONSOLE_TRACE
			if (packetId > -1)
				Trace("Handle packet (" + rudp.Handle + ")(" + channel + "):" + packetId);
#endif

			//---- Advertised window
			rudp._controlWindow.OnReceiveAdvertisedWindow(advertisedWindowSize);

			//---- Handle ACKs
			HandleACKs(rudp, slot1, slot2, slot3, slot4);

			if (channel == RUDPPacketChannel.ACK)
				return;

			//---- Non reliable messages
			if (packetId < 0)
			{
				//-- Bandwidth
				if (channel == RUDPPacketChannel.Bandwidth01)
				{
					PushPacketToSend(rudp, false, RUDPPacketChannel.BandwidthResponse01, null, 0, 0);
					return;
				}
				else if (channel == RUDPPacketChannel.Bandwidth02)
				{
					PushPacketToSend(rudp, false, RUDPPacketChannel.BandwidthResponse02, payload, 0, 8);
					return;
				}
				else if (channel == RUDPPacketChannel.BandwidthResponse01)
				{
					rudp._bandwidthResponse01TS = HiResTimer.MicroSeconds;
				}
				else if (channel == RUDPPacketChannel.BandwidthResponse02)
				{
					//---- Calculate bandwidth
					// Bdw (Bytes / milli-sec)
					long now = HiResTimer.MicroSeconds;
					double delay = (now - rudp._bandwidthResponse01TS) / 1000;
					if (delay < 0.001)
						delay = 0.001;

					// Arrival Speed
					double arrivalSpeed = (RUDPHeaderLength + UDPHeaderLength) / delay;

					// RTT
					double currentRtt = (now - BinaryHelper.ReadInt(payload, 0)) / 1000;
					if (currentRtt < 0.001)
						currentRtt = 0.001;

					// BDP = Bandwidth(Byte / Ms) * RTT;
					double bandwidth = (long)(arrivalSpeed * currentRtt);
					rudp._bandwidth = (long)(rudp._bandwidth * 0.875f + bandwidth * 0.125f);
				}

				//-- MTU Tuning
				else if (channel == RUDPPacketChannel.MTUTuning)
				{
					rudp._pmtuDiscovery.OnReceiveProbe(payload.Length);
					return;
				}
				else if (channel == RUDPPacketChannel.MTUTuningACK)
				{
					rudp._pmtuDiscovery.OnReceiveProbeACK(payload);
					return;
				}

				//if ((rudp._incomingNonReliablePackets.Count * rudp._mtu) >= rudp._receiveSize)
				//return;

				RUDPIngoingPacket nonReliablePacket = new RUDPIngoingPacket(rudp, packetId, payload, channel, HiResTimer.MicroSeconds);
				rudp._incomingPackets.AddPacket(nonReliablePacket);

				rudp.HandleNextUserPacket(false);
				return;
			}

			//---- Do not process a duplicated packets
			bool isDuplicatedPacket;
			isDuplicatedPacket = (packetId <= rudp._incomingPackets.CurrentPacketId);
			if (!isDuplicatedPacket)
				isDuplicatedPacket = rudp._incomingPackets.ContainsPacket(packetId);

			//---- Can I receive the packet now ?
			bool canReceive = rudp._controlWindow.CanReceive(packetId, payload.Length);

			//---- Send the ACK
			if (channel != RUDPPacketChannel.Ping && channel != RUDPPacketChannel.PingRendezVous)
				if (canReceive ||	// Can receive, then we send ACK
					(!canReceive && isDuplicatedPacket))	// Is duplicated, then already in the list -> send another ACK
					rudp._sackWindow.OnReceivePacket(packetId);

			//---- Check if we can handle this message
			if (!canReceive || isDuplicatedPacket)
				return;

			//---- If we are not connected, we cannot hanlde messages ! We need a connection before.
			if (rudp._status != RUDPSocketStatus.Connected && channel == RUDPPacketChannel.UserPacket)
				return;

			//---- Check for Out of order packets
			if (rudp._incomingPackets.Count > 0)
			{
				int greaterPacketId = rudp._incomingPackets.LastPacketId;
				if (packetId != greaterPacketId + 1)
				{
					byte[] oooPayload = new byte[8];
					// start packet
					BinaryHelper.WriteInt(greaterPacketId + 1, oooPayload, 0);
					// end packet
					BinaryHelper.WriteInt(packetId - 1, oooPayload, 4);
					PushPacketToSend(rudp, false, RUDPPacketChannel.OutOfOrder, oooPayload, 0, 8);
				}
			}

			//---- Receive Out of order notification
			if (channel == RUDPPacketChannel.OutOfOrder)
			{
				rudp._controlWindow.OnOutOfOrder(BinaryHelper.ReadInt(payload, 0), BinaryHelper.ReadInt(payload, 4));
			}

			//---- TEAR DOWN
			if (channel == RUDPPacketChannel.TearDown)
			{
				// Initiate the close process
				if (rudp._status == RUDPSocketStatus.Connected)
				{
					// Notify control window
					rudp._controlWindow.OnReceive(null);

					// Start shutdown
					AsyncShutdown(rudp);
				}

				return;
			}

			//---- Add the packet to incoming list
			RUDPIngoingPacket packet = new RUDPIngoingPacket(rudp, packetId, payload, channel, HiResTimer.MicroSeconds);

			// Notify control window
			rudp._controlWindow.OnReceive(packet);
			rudp._incomingPackets.AddPacket(packet);

			//------ Handle the ordered ingoing packets
			rudp.HandleNextUserPacket(false);
		}
Пример #9
0
 internal void OnReceiveProcessed(RUDPIngoingPacket packet)
 {
     Interlocked.Exchange(ref _rwnd, _rwnd - packet.Payload.Length);
 }
Пример #10
0
        internal void HandleNextUserPacket(bool forceAsyncCall)
        {
            if (_asyncResultReceive == null)
            {
                return;
            }

            RUDPReceiveIAsyncResult asyncResult;
            RUDPIngoingPacket       packet = null;

            lock (_handleNextUserPacketLock)
            {
                if (_incomingPackets.Count < 1)
                {
                    return;
                }

                asyncResult = _asyncResultReceive;
                if (_asyncResultReceive == null)
                {
                    return;
                }

                //-- Clean the list
                while (_incomingPackets.Count > 0)
                {
                    // Get the current packet
                    packet = _incomingPackets.RemoveNextPacket();

                    // No more packet
                    if (packet == null)
                    {
                        return;
                    }

                    // Ordered packet
                    if (packet.Channel != RUDPPacketChannel.UserPacket)
                    {
                        _controlWindow.OnReceiveProcessed(packet);
                    }
                    else
                    {
                        break;                         // It is the next message to process.
                    }
                }

                //---- Check it is not null
                if (packet == null)
                {
                    return;
                }

                _asyncResultReceive = null;
            }

            //---- Receive
            if (asyncResult != null)
            {
                _controlWindow.OnReceiveProcessed(packet);
                OnEndReceive(RUDPSocketError.Success, packet, forceAsyncCall, asyncResult);
            }
        }
Пример #11
0
 internal void OnEndReceive(RUDPSocketError error, RUDPIngoingPacket packet, bool forceAsyncCall, RUDPReceiveIAsyncResult asyncResult)
 {
     asyncResult.Packet         = packet;
     asyncResult.ForceAsyncCall = forceAsyncCall;
     asyncResult.SetAsCompleted(error, false);
 }
Пример #12
0
		internal void OnEndReceive(RUDPSocketError error, RUDPIngoingPacket packet, bool forceAsyncCall, RUDPReceiveIAsyncResult asyncResult)
		{
			asyncResult.Packet = packet;
			asyncResult.ForceAsyncCall = forceAsyncCall;
			asyncResult.SetAsCompleted(error, false);
		}