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); } } }
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); }
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); } }
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; } }