예제 #1
0
        public void TestReliableSequencedChannelReceiveOutOfSequence()
        {
            ReliableSequencedChannel sender   = new ReliableSequencedChannel(0);
            ReliableSequencedChannel receiver = new ReliableSequencedChannel(0);

            RemotePeer      firstPeer;
            ChanneledPacket firstPacket;
            {
                // Create first packet with sequence 1
                firstPeer = new RemotePeer();// (new IPEndPoint(IPAddress.Any, 5670));
                ulong sessionId = (ulong)0;
                firstPeer.ChallengeResult = sessionId;
                byte[] payload = new byte[0];
                firstPacket = sender.CreateOutgoingMessage(payload, 0, payload.Length);
            }
            {
                Random random = new Random(0);
                foreach (int i in Enumerable.Range(1, 100).OrderBy(x => random.Next()))
                {
                    RemotePeer fakePeer  = new RemotePeer(); // (new IPEndPoint(IPAddress.Any, 5670));
                    ulong      sessionId = (ulong)i;
                    fakePeer.ChallengeResult = sessionId;
                    byte[] payload = new byte[random.Next(0, 1024)];
                    random.NextBytes(payload);
                    ChanneledPacket         sent      = sender.CreateOutgoingMessage(payload, 0, payload.Length);
                    byte[]                  buffer    = new byte[5000];
                    int                     oSize     = sent.Write(buffer, fakePeer);
                    ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandleIncomingMessagePoll(buffer, oSize, out bool hasMore);
                    Assert.IsNull(incPacket);
                }
            }

            {
                byte[] buffer = new byte[5000];
                int    oSize  = firstPacket.Write(buffer, firstPeer);
                ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandleIncomingMessagePoll(buffer, oSize, out bool hasMore);

                Assert.NotNull(incPacket);
                Assert.IsTrue(incPacket.Payload.Length == 0);
                Assert.IsTrue(hasMore);
            }

            {
                Random random = new Random(0);
                foreach (int i in Enumerable.Range(1, 100).OrderBy(x => random.Next()))
                {
                    ulong  sessionId = (ulong)i;
                    byte[] payload   = new byte[random.Next(0, 1024)];
                    random.NextBytes(payload);
                    ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandlePoll();
                    Assert.NotNull(incPacket);
                    CollectionAssert.AreEqual(incPacket.Payload, payload);
                }
            }
        }
예제 #2
0
파일: LocalPeer.cs 프로젝트: Vyxlose/Rudel
        public void Send(RemotePeer peer, byte channel, byte[] payload, int offset, int length)
        {
            ChanneledPacket packet = peer.Channels[channel].CreateOutgoingMessage(payload, offset, length);

            if (peer.ConnectionState != ConnectState.Connected)
            {
                // TODO: Shit hit the fan
            }

            SendPacket(packet, peer);
        }
예제 #3
0
        public void TestReliableSequencedChannelReceiveInSequence()
        {
            ReliableSequencedChannel sender   = new ReliableSequencedChannel(0);
            ReliableSequencedChannel receiver = new ReliableSequencedChannel(0);

            Random random = new Random(0);

            for (int i = 0; i < 100000; i++)
            {
                RemotePeer fakePeer  = new RemotePeer();// new IPEndPoint(IPAddress.Any, 5670));
                ulong      sessionId = RandomUtils.GetULong(false);
                fakePeer.ChallengeResult = sessionId;
                int    payLength = random.Next(0, 1024);
                byte[] payload   = new byte[payLength];
                random.NextBytes(payload);
                ChanneledPacket         sent      = sender.CreateOutgoingMessage(payload, 0, payload.Length);
                byte[]                  buffer    = new byte[5000];
                int                     oSize     = sent.Write(buffer, fakePeer);
                ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandleIncomingMessagePoll(buffer, oSize, out bool hasMore);
                Assert.IsNotNull(incPacket, "it:" + i);
                Assert.AreEqual(payLength, incPacket.Payload.Length);
                CollectionAssert.AreEqual(payload, incPacket.Payload);
            }
        }
예제 #4
0
파일: LocalPeer.cs 프로젝트: Vyxlose/Rudel
        private void HandlePacket(byte[] data, int length, EndPoint fromEndpoint)
        {
            if (length < 1)
            {
                // TODO: Shit hit the fan
            }

            PacketType type = (PacketType)data[0];

            switch (type)
            {
            case PacketType.ConnectionRequest:
            {
                ConnectionRequestPacket connectionRequest = new ConnectionRequestPacket();
                if (connectionRequest.Read(data, length) && !PendingPeers.ContainsKey(new ConnectKey(fromEndpoint, connectionRequest.ClientRandom)))
                {
                    ulong localSessionPart = RandomUtils.GetULong(Constants.USE_CRYPTO_RANDOM);

                    RemotePeer peer = new RemotePeer()
                    {
                        ChallengeData           = connectionRequest.ClientRandom,
                        RemoteEndpoint          = fromEndpoint,
                        ConnectionState         = ConnectState.WaitingForChallengeResponse,
                        ChallengeSeed           = localSessionPart,
                        ChallengeResult         = localSessionPart ^ connectionRequest.ClientRandom,
                        LastIncomingMessageDate = DateTime.Now
                    };

                    PendingPeers.Add(new ConnectKey(fromEndpoint, connectionRequest.ClientRandom), peer);

                    ChallengePacket packet = new ChallengePacket(peer.ChallengeData, peer.ChallengeSeed);

                    SendPacket(packet, peer);

                    for (int i = 0; i < Constants.CONNECTION_SEGMENT_RETRIES - 1; i++)
                    {
                        _network.PacketScheduler.Add(DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, Constants.CONNECTION_SEGMENT_RETRY_TIMEOUT * i)), new ScheduledPacket()
                            {
                                Packet     = packet,
                                LocalPeer  = this,
                                RemotePeer = peer
                            });
                    }
                }
            }
            break;

            case PacketType.Challenge:
            {
                ChallengePacket challenge = new ChallengePacket();
                if (challenge.Read(data, length) && PendingPeers.ContainsKey(new ConnectKey(fromEndpoint, challenge.ClientRandom)))
                {
                    RemotePeer peer = PendingPeers[new ConnectKey(fromEndpoint, challenge.ClientRandom)];
                    if (peer.ConnectionState == ConnectState.WaitingForChallenge)
                    {
                        peer.CreateChannels(_network.ChannelTypes);
                        peer.LastIncomingMessageDate = DateTime.Now;
                        peer.ChallengeData           = challenge.ServerRandom;
                        peer.ChallengeResult         = peer.ChallengeData ^ peer.ChallengeSeed;
                        peer.ConnectionState         = ConnectState.Connected;

                        PendingPeers.Remove(new ConnectKey(fromEndpoint, challenge.ClientRandom));
                        Connected.Add(fromEndpoint, peer);

                        incomingEvents.Enqueue(new NetworkEvent()
                            {
                                EventType  = EventType.Connect,
                                Packet     = null,
                                RemotePeer = peer,
                                LocalPeer  = this
                            });

                        ChallengeResponsePacket packet = new ChallengeResponsePacket(peer.ChallengeSeed, peer.ChallengeData, peer.ChallengeResult);

                        SendPacket(packet, peer);

                        for (int i = 0; i < Constants.CONNECTION_SEGMENT_RETRIES - 1; i++)
                        {
                            _network.PacketScheduler.Add(DateTime.Now.Add(new TimeSpan(0, 0, 0, 0, Constants.CONNECTION_SEGMENT_RETRY_TIMEOUT * i)), new ScheduledPacket()
                                {
                                    Packet     = packet,
                                    LocalPeer  = this,
                                    RemotePeer = peer
                                });
                        }
                    }
                }
            }
            break;

            case PacketType.ChallengeResponse:
            {
                ChallengeResponsePacket challengeResponse = new ChallengeResponsePacket();
                if (challengeResponse.Read(data, length) && PendingPeers.ContainsKey(new ConnectKey(fromEndpoint, challengeResponse.ClientRandom)))
                {
                    RemotePeer peer = PendingPeers[new ConnectKey(fromEndpoint, challengeResponse.ClientRandom)];
                    if (peer.ConnectionState == ConnectState.WaitingForChallengeResponse && peer.ChallengeResult == challengeResponse.ChallengeResponse)
                    {
                        peer.CreateChannels(_network.ChannelTypes);
                        peer.LastIncomingMessageDate = DateTime.Now;
                        peer.ConnectionState         = ConnectState.Connected;
                        PendingPeers.Remove(new ConnectKey(fromEndpoint, challengeResponse.ClientRandom));
                        Connected.Add(fromEndpoint, peer);
                        incomingEvents.Enqueue(new NetworkEvent()
                            {
                                EventType  = EventType.Connect,
                                Packet     = null,
                                RemotePeer = peer,
                                LocalPeer  = this
                            });
                    }
                }
            }
            break;

            case PacketType.Data:
            {
                ChanneledPacket channeledPacket = new ChanneledPacket();
                if (channeledPacket.Read(data, length) && Connected.ContainsKey(fromEndpoint))
                {
                    RemotePeer peer = Connected[fromEndpoint];
                    if (peer.ConnectionState == ConnectState.Connected)
                    {
                        ChanneledPacket incomingPacket = peer.Channels[channeledPacket.Channel].HandleIncomingMessagePoll(data, length, out bool hasMore);
                        while (incomingPacket != null)
                        {
                            peer.LastIncomingMessageDate = DateTime.Now;
                            incomingEvents.Enqueue(new NetworkEvent()
                                {
                                    EventType  = EventType.Data,
                                    Packet     = incomingPacket,
                                    RemotePeer = peer,
                                    LocalPeer  = this
                                });
                            if (!hasMore)
                            {
                                break;
                            }
                            incomingPacket = peer.Channels[channeledPacket.Channel].HandlePoll();
                        }
                    }
                }
            }
            break;

            case PacketType.Disconnect:
            {
                DisconnectPacket disconnectPacket = new DisconnectPacket();
                if (disconnectPacket.Read(data, length) && Connected.ContainsKey(fromEndpoint))
                {
                    RemotePeer peer = Connected[fromEndpoint];
                    peer.ConnectionState = ConnectState.Disconnected;
                    Connected.Remove(fromEndpoint);
                    incomingEvents.Enqueue(new NetworkEvent()
                        {
                            EventType  = EventType.Disconnect,
                            Packet     = null,
                            RemotePeer = peer,
                            LocalPeer  = this
                        });
                }
            }
            break;

            case PacketType.Ack:
            {
                AckPacket ackPacket = new AckPacket();
                if (ackPacket.Read(data, length) && Connected.ContainsKey(fromEndpoint))
                {
                    RemotePeer peer = Connected[fromEndpoint];
                    if (peer.Channels[ackPacket.Channel].SupportsAck)
                    {
                        peer.Channels[ackPacket.Channel].HandleAck(ackPacket);
                    }
                }
            }
            break;
            }
        }