/// <summary> /// Create RDPUDP_ACK_VECTOR_HEADER Structure for packet sending /// </summary> /// <returns></returns> public RDPUDP_ACK_VECTOR_HEADER CreateAckVectorHeader() { RDPUDP_ACK_VECTOR_HEADER ackVectorHeader = new RDPUDP_ACK_VECTOR_HEADER(); if (inPacketDic.Count == 0) { // Not receive any source packet ackVectorHeader.uAckVectorSize = 0; ackVectorHeader.AckVectorElement = null; ackVectorHeader.Padding = null; } else { lock (inPacketDic) { // Generate an ACK header. List <AckVector> ackVectorElements = new List <AckVector>(); VECTOR_ELEMENT_STATE currentState = inPacketDic.ContainsKey(InSnAckOfAcksSeqNum) ? VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED : VECTOR_ELEMENT_STATE.DATAGRAM_NOT_YET_RECEIVED; AckVector ackVectorElement = new AckVector(); ackVectorElement.State = currentState; ackVectorElement.Length = 0; // RLE encoding. for (uint i = InSnAckOfAcksSeqNum + 1; i <= SnSourceAck; i++) { currentState = inPacketDic.ContainsKey(i) ? VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED : VECTOR_ELEMENT_STATE.DATAGRAM_NOT_YET_RECEIVED; // 0x40 is the max length of state length, of which I believe sould be indicate from soket config or types config not hard code here. if (currentState != ackVectorElement.State || ackVectorElement.Length >= 0x40) { // If current state differs from last state, assign a new ack vector. ackVectorElements.Add(ackVectorElement); ackVectorElement = new AckVector(); ackVectorElement.State = currentState; ackVectorElement.Length = 0; } else { // Else count++. ackVectorElement.Length++; } } ackVectorElements.Add(ackVectorElement); ackVectorHeader.uAckVectorSize = (ushort)ackVectorElements.Count; ackVectorHeader.AckVectorElement = ackVectorElements.ToArray(); // ACK Vector created for all received packet, set number of received packets for ACK to 0 sourceNumNotAcked = 0; } } return(ackVectorHeader); }
/// <summary> /// Wait for an ACK packet which meets certain conditions. /// </summary> /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param> /// <param name="timeout">Wait time.</param> /// <param name="expectAckVectors">Expected ack vectors.</param> /// <param name="hasFlag">Flags, which the ACK packet must contain.</param> /// <param name="notHasFlag">Flags, which the ACK packet must no contain.</param> /// <returns></returns> private RdpeudpPacket WaitForACKPacket(TransportMode udpTransportMode, TimeSpan timeout, AckVector[] expectAckVectors = null, RDPUDP_FLAG hasFlag = 0, RDPUDP_FLAG notHasFlag = 0) { RdpeudpSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; } DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { RdpeudpPacket ackPacket = rdpeudpSocket.ExpectACKPacket(endTime - DateTime.Now); if (ackPacket!=null) { if (expectAckVectors != null) { if (!(ackPacket.ackVectorHeader.HasValue && CompareAckVectors(ackPacket.ackVectorHeader.Value.AckVectorElement, expectAckVectors))) { continue; } } if (hasFlag != 0) { if ((ackPacket.fecHeader.uFlags & hasFlag) != hasFlag) { continue; } } if (notHasFlag != 0) { if ((ackPacket.fecHeader.uFlags & notHasFlag) != 0) { continue; } } return ackPacket; } } return null; }
/// <summary> /// Compare two AckVectors. /// </summary> /// <param name="vector1">Ack Vector 1.</param> /// <param name="vector2">Ack Vector 2.</param> /// <returns></returns> private bool CompareAckVectors(AckVector[] vector1, AckVector[] vector2) { int posForVector1 = 0; int posForVector2 = 0; int length1 = vector1[posForVector1].Length+1; int length2 = vector2[posForVector2].Length+1; while (posForVector1 < vector1.Length && posForVector2 < vector2.Length) { if (vector1[posForVector1].State != vector2[posForVector2].State) { return false; } if (length1 == length2) { posForVector1++; posForVector2++; if (!(posForVector1 < vector1.Length && posForVector2 < vector2.Length)) break; length1 = vector1[posForVector1].Length+1; length2 = vector2[posForVector2].Length+1; } else if (length1 > length2) { length1 -= length2; posForVector2++; if (!(posForVector1 < vector1.Length && posForVector2 < vector2.Length)) break; length2 = vector2[posForVector2].Length + 1; } else { length2 -= length1; posForVector1++; if (!(posForVector1 < vector1.Length && posForVector2 < vector2.Length)) break; length1 = vector1[posForVector1].Length + 1; } } if (posForVector1 < vector1.Length || posForVector2 < vector2.Length) { return false; } return true; }
/// <summary> /// Create RDPUDP_ACK_VECTOR_HEADER Structure for packet sending /// </summary> /// <returns></returns> public RDPUDP_ACK_VECTOR_HEADER CreateAckVectorHeader() { RDPUDP_ACK_VECTOR_HEADER ackVectorHeader = new RDPUDP_ACK_VECTOR_HEADER(); if (inPacketDic.Count == 0) { // Not receive any source packet ackVectorHeader.uAckVectorSize = 0; ackVectorHeader.AckVectorElement = null; ackVectorHeader.Padding = null; } else { lock (inPacketDic) { // Generate an ACK header. List<AckVector> ackVectorElements = new List<AckVector>(); VECTOR_ELEMENT_STATE currentState = inPacketDic.ContainsKey(InSnAckOfAcksSeqNum) ? VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED : VECTOR_ELEMENT_STATE.DATAGRAM_NOT_YET_RECEIVED; AckVector ackVectorElement = new AckVector(); ackVectorElement.State = currentState; ackVectorElement.Length = 0; // RLE encoding. for (uint i = InSnAckOfAcksSeqNum + 1; i <= SnSourceAck; i++) { currentState = inPacketDic.ContainsKey(i) ? VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED : VECTOR_ELEMENT_STATE.DATAGRAM_NOT_YET_RECEIVED; // 0x40 is the max length of state length, of which I believe sould be indicate from soket config or types config not hard code here. if (currentState != ackVectorElement.State || ackVectorElement.Length >= 0x40) { // If current state differs from last state, assign a new ack vector. ackVectorElements.Add(ackVectorElement); ackVectorElement = new AckVector(); ackVectorElement.State = currentState; ackVectorElement.Length = 0; } else { // Else count++. ackVectorElement.Length++; } } ackVectorElements.Add(ackVectorElement); ackVectorHeader.uAckVectorSize = (ushort)ackVectorElements.Count; ackVectorHeader.AckVectorElement = ackVectorElements.ToArray(); // ACK Vector created for all received packet, set number of received packets for ACK to 0 sourceNumNotAcked = 0; } } return ackVectorHeader; }
public void S2_DataTransfer_SequenceNumberWrapAround() { Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; foreach (TransportMode transportMode in transportModeArray) { this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} UDP connection.", transportMode); initSequenceNumber = uint.MaxValue - 3; this.EstablishUDPConnection(transportMode, waitTime, true); this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} RDPEMT connection.", transportMode); this.EstablishRdpemtConnection(transportMode, waitTime); if (getSourcePacketSequenceNumber(transportMode) > getSnInitialSequenceNumber(transportMode)) { this.TestSite.Log.Add(LogEntryKind.Comment, "Not wrap around yet, Send one RDPUDP packet."); this.SendNextValidUdpPacket(transportMode); } this.TestSite.Log.Add(LogEntryKind.Comment, "Already wrap around, Send three RDPUDP packet again."); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); #region Create Expect Ack Vectors List<AckVector> expectedAckVectors = new List<AckVector>(); AckVector ackVector = new AckVector(); ackVector.State = VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED; ackVector.Length = (byte)(getSourcePacketSequenceNumber(transportMode) + (uint.MaxValue- getSnInitialSequenceNumber(transportMode))); expectedAckVectors.Add(ackVector); #endregion Create Expect Ack Vectors this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to send an ACK packet to acknowledge the receipt correctly"); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, expectedAckVectors.ToArray()); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK to correctly acknowledge the receipt of source packet. Transport mode is {0}", transportMode); } }
public void S2_DataTransfer_AcknowledgeTest_AcknowlegeLossyPackage() { Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; foreach (TransportMode transportMode in transportModeArray) { this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} UDP connection.", transportMode); this.EstablishUDPConnection(transportMode, waitTime, true); this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} RDPEMT connection.", transportMode); this.EstablishRdpemtConnection(transportMode, waitTime); this.TestSite.Log.Add(LogEntryKind.Comment, "Send one RDPUDP packet."); this.SendNextValidUdpPacket(transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Send the second RDPUDP packet, don't really send it, it is as a lost packet"); RdpeudpPacket losspacket = this.GetNextValidUdpPacket(transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Send the third and the forth RDPUDP packet."); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); #region Create Expect Ack Vectors List<AckVector> expectedAckVectors = new List<AckVector>(); // All packet before the lost one are received. AckVector ackVector = new AckVector(); ackVector.State = VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED; ackVector.Length = (byte)(losspacket.sourceHeader.Value.snSourceStart - getSnInitialSequenceNumber(transportMode) - 2); expectedAckVectors.Add(ackVector); // One packet lost. ackVector = new AckVector(); ackVector.State = VECTOR_ELEMENT_STATE.DATAGRAM_NOT_YET_RECEIVED; ackVector.Length = 0; expectedAckVectors.Add(ackVector); // Two packet received. ackVector = new AckVector(); ackVector.State = VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED; ackVector.Length = 1; expectedAckVectors.Add(ackVector); #endregion Create Expect Ack Vectors // Expect an ACK packet with expected acknowledge information. this.TestSite.Log.Add(LogEntryKind.Comment, "expect an ACK packet with expected acknowledge information."); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, expectedAckVectors.ToArray()); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK to acknowledge the receipt of source packets correctly, transport mode is {0}.", transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Send the second RDPUDP packet, which is lost before"); this.SendPacket(transportMode, losspacket); #region Create Expect Ack Vectors expectedAckVectors.Clear(); // All packet before the lost one are received. ackVector = new AckVector(); ackVector.State = VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED; ackVector.Length = (byte)(losspacket.sourceHeader.Value.snSourceStart - getSnInitialSequenceNumber(transportMode)-2); // The lost one and the next two packed are received too. ackVector.Length += 3; expectedAckVectors.Add(ackVector); #endregion // Expect an ACK packet with acknowledge all packets recieved. this.TestSite.Log.Add(LogEntryKind.Comment, "expect an ACK packet with acknowledge all packets received."); ackpacket = WaitForACKPacket(transportMode, waitTime, expectedAckVectors.ToArray()); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK to acknowledge the receipt of source packets correctly, transport mode is {0}.", transportMode); } }
public void S2_DataTransfer_ClientReceiveData() { Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; foreach (TransportMode transportMode in transportModeArray) { this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} UDP connection.", transportMode); this.EstablishUDPConnection(transportMode, waitTime, true); this.TestSite.Log.Add(LogEntryKind.Comment, "Send the first RDPEUDP Source packet"); RdpeudpPacket packet = this.GetFirstValidUdpPacket(transportMode); this.SendPacket(transportMode, packet); #region Create Expect Ack Vectors List<AckVector> expectedAckVectors = new List<AckVector>(); AckVector ackVector = new AckVector(); ackVector.State = VECTOR_ELEMENT_STATE.DATAGRAM_RECEIVED; ackVector.Length = (byte)(packet.sourceHeader.Value.snSourceStart - getSnInitialSequenceNumber(transportMode) - 1); expectedAckVectors.Add(ackVector); #endregion Create Expect Ack Vectors this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to send an ACK packet to acknowledge the receipt"); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, expectedAckVectors.ToArray()); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK to acknowledge the receipt of source packet. Transport mode is {0}", transportMode); } }