public void HandleIncomingPacket(GenericPacket p) { Console.WriteLine(String.Format("Incoming packet Seq#{0} Ack#{1}", p.Seq, p.Ack)); if (congestionController.CheckPacket(p)) { Console.WriteLine(String.Format("Packet ACCEPTED because its in of order Seq#{0} Ack#{1}", p.Seq, p.Ack)); if (this.incomingPacketInterceptor != null) { incomingPacketInterceptor.Invoke(p); } GenericPacket ackPacket = new GenericPacketMock(0); ackPacket.Ack = p.Seq; congestionController.SendAck(ackPacket); } else if (congestionController.CheckResendAck(p)) { Console.WriteLine(String.Format("Resending ACK because this is an already accepted packet out of order Seq#{0} Ack#{1}", p.Seq, p.Ack)); GenericPacket ackPacket = new GenericPacketMock(0); ackPacket.Ack = p.Seq; congestionController.SendAck(ackPacket); } else if (p.Seq != 0) { Console.WriteLine(String.Format("Packet IGNORED because its out of order Seq#{0} Ack#{1}", p.Seq, p.Ack)); } }
internal void TestReliablity(CongestionControlBase congestionControl) { SetupMembers(); this.congestionControlBase = congestionControl; Assert.IsNotNull(congestionControlBase, "You must instantiate the congestion control base before running tests"); GenericPacketMock p1 = new GenericPacketMock(1); GenericPacketMock p2 = new GenericPacketMock(2); GenericPacketMock p3 = new GenericPacketMock(3); GenericPacketMock p4 = new GenericPacketMock(4); GenericPacketMock p5 = new GenericPacketMock(5); GenericPacketMock p6 = new GenericPacketMock(6); UInt16 expectedSeq = 1; bool triggered = false; socketMock2.InterceptIncomingPacket(packet => { Assert.IsTrue(packet.Seq == expectedSeq, String.Format("Expected packet with seq {0} and got {1} instead", expectedSeq, packet.Seq)); triggered = true; GenericPacket ackPacket = new GenericPacketMock(0); ackPacket.Ack = packet.Seq; }); tunnel.SendPacket(p1); Assert.IsTrue(triggered); }
public void TestCongestion() { GenericPacketMock packet1 = new GenericPacketMock(1); GenericPacketMock packet2 = new GenericPacketMock(2); GenericPacketMock packet3 = new GenericPacketMock(3); GenericPacketMock packet4 = new GenericPacketMock(4); GenericPacketMock packet5 = new GenericPacketMock(5); GenericPacketMock packet6 = new GenericPacketMock(6); GenericPacketMock packet7 = new GenericPacketMock(7); mockSock.InterceptIncomingPacket((Tunneler.Packet.GenericPacket p) => { }); this.congestion.SendPacket(packet1); }
/// <summary> /// Tests the reliablity components of the underlying protocol. In order to do that, /// we need to simulate sending a number of packets in-order, out of order, in-time /// and out of time (to simulate dropped packets). This is an extremly granular test /// of the packets themselves, a seperate message reliabilty test exists to ensure /// that pipes receive their data and congestion control does its job or resending /// unacked packets. /// /// The concrete congestion tests will set up two controller mocks and pass them into /// this function which will simulate communications between the two points. This function /// assumes that all of the objects have been correctly /// </summary> /// <param name="ep1">Ep1.</param> /// <param name="ep2">Ep2.</param> /// <param name="maxTimeoutPerPacket">A maximum timeout per packet /// before packetloss is deemed a failure</param> internal void TestReliablityAtomic(TunnelCongestionControllerMock ep1, TunnelCongestionControllerMock ep2, Int32 maxTimeOutPerPacket) { Assert.IsNotNull(mPs1, "You must set ep1 to use mPs1 as its packet sender"); Assert.IsNotNull(mPs2, "You must set ep2 to use mPs2 as its packet sender"); GenericPacketMock p1 = new GenericPacketMock(1); GenericPacketMock p2 = new GenericPacketMock(2); GenericPacketMock p3 = new GenericPacketMock(3); GenericPacketMock p4 = new GenericPacketMock(4); Queue <int> expectedAcks = new Queue <int> (); for (int i = 1; i <= 4; i++) { expectedAcks.Enqueue(i); } //the test sends packets from ep1 to ep2 int curCount = 1; mPs1.InterceptOutgoingPacket(p => { //ensure that the acks come in order ep2.HandleIncomingPacket(p); }); mPs2.InterceptOutgoingPacket(p => { ep1.HandleIncomingPacket(p); Assert.IsTrue(expectedAcks.Dequeue() == p.Ack, "Failed at packet seq" + p.Ack); }); ep1.SendPacket(p1); ep1.SendPacket(p2); ep1.SendPacket(p4); ep1.SendPacket(p3); }
public void TestWindowIncreaseDecrease() { GenericPacketMock packet1 = new GenericPacketMock(1); GenericPacketMock packet2 = new GenericPacketMock(2); GenericPacketMock packet3 = new GenericPacketMock(3); GenericPacketMock packet4 = new GenericPacketMock(4); GenericPacketMock packet5 = new GenericPacketMock(5); GenericPacketMock packet6 = new GenericPacketMock(6); GenericPacketMock packet7 = new GenericPacketMock(7); Assert.IsTrue(this.congestion.CongestionWindowSize == 1); this.congestion.SendPacket(packet1); this.congestion.Acked(packet1.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 2); this.congestion.SendPacket(packet1); this.congestion.Acked(packet1.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 4); this.congestion.SendPacket(packet2); this.congestion.Acked(packet2.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 5, String.Format("Expected congestion window to be {0} but was {1}", 5, this.congestion.CongestionWindowSize)); this.congestion.SendPacket(packet3); this.congestion.Acked(packet3.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 5); this.congestion.SendPacket(packet4); this.congestion.Acked(packet4.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 5); this.congestion.SendPacket(packet5); this.congestion.Acked(packet5.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 5); this.congestion.SendPacket(packet6); this.congestion.PacketDropped(3, 250); Assert.IsTrue(this.congestion.CongestionWindowSize == 2); this.congestion.SendPacket(packet7); this.congestion.Acked(packet7.Seq); Assert.IsTrue(this.congestion.CongestionWindowSize == 4, "Congestion window size should be 3"); }
/// <summary> /// This test launches multiple tests and sends a series of packets through an object /// that simulates packet loss. The packet loss will medium will randomly simulate /// RTT delays, MTU size differences and just packet loss. /// </summary> internal void TestReliability(TunnelCongestionControllerMock ep1, TunnelSocketSendIntercept sock1, TunnelCongestionControllerMock ep2, TunnelSocketSendIntercept sock2, int lossPercentage, UInt32 dgramSize) { LossyConnection connection = new LossyConnection(lossPercentage); //hook ep1 to ep2 //sending from ep1 to ep2 sock1.SetSendInterceptor(p => { //outgoing packet needs to be bubbled into sock2 connection.SendPacket(p, ep2); }); //ep2 sends an ack to ep1 sock2.SetSendInterceptor(p => { //add test for acks (they should always come in order) connection.SendPacket(p, ep1); }); int curAck = 1; ep1.SetIncomingPacketInterceptor(p => { //should receive Ack's in order Assert.IsTrue(curAck == p.Ack, "Acks should be received in order"); }); StringBuilder buildString = new StringBuilder(); ep2.SetIncomingPacketInterceptor(p => { GenericPacketMock gp = (GenericPacketMock)p; buildString.Append(Encoding.ASCII.GetString(gp.GetPayload())); }); //the test executes on a seperate thread Thread testThread = new Thread(new ThreadStart(() => { byte[] txt = Encoding.ASCII.GetBytes(this.sendText); int size = 576 - 8 - 80; uint seq = 1; ArrayList <GenericPacketMock> packets = new ArrayList <GenericPacketMock>(); int numPackets = txt.Length / size; int overFlow = txt.Length % size; if (overFlow > 0) { numPackets += 1; } for (int i = 0; i < numPackets; i++) { int sizeSubArray = Math.Min(size, txt.Length - (i * size)); byte[] sub = new byte[sizeSubArray]; Array.Copy(txt, i * size, sub, 0, sizeSubArray); GenericPacketMock p = new GenericPacketMock(seq); p.SetPayload(sub); seq++; packets.Add(p); } foreach (GenericPacket p in packets) { ep1.SendPacket(p); } })); testThread.Start(); Thread.Sleep(1000); Assert.IsTrue(this.sendText.Equals(buildString.ToString()), buildString.ToString()); }