public void S1_Connection_Keepalive_ClientSendKeepAlive() { TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; CheckPlatformCompatibility(ref transportModeArray); CheckSecurityProtocolForMultitransport(); Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); foreach (TransportMode transportMode in transportModeArray) { DoUntilSucceed(() => { 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); return(this.EstablishRdpemtConnection(transportMode, waitTime)); }, this.waitTime * 5, TimeSpan.FromSeconds(0.5), "RDPEMT tunnel creation failed"); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to send an ACK packet to keep alive or acknowledge the receipt"); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK to keep alive or acknowledge the receipt of source packet. Transport mode is {0}", transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to resend the ACK packet to keep alive"); ackpacket = WaitForACKPacket(transportMode, waitTime); Site.Assert.IsNotNull(ackpacket, "Client should resend the ACK packet to keep alive. Transport mode is {0}", transportMode); } }
public void S1_Connection_Keepalive_ClientSendKeepAlive() { CheckSecurityProtocolForMultitransport(); 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, "Expect RDP client to send an ACK packet to keep alive or acknowledge the receipt"); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK to keep alive or acknowledge the receipt of source packet. Transport mode is {0}", transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to resend the ACK packet to keep alive"); ackpacket = WaitForACKPacket(transportMode, waitTime); Site.Assert.IsNotNull(ackpacket, "Client should resend the ACK packet to keep alive. 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); } }
/// <summary> /// Constructor /// </summary> /// <param name="eudpSocket">RDPEUDP Socket, which is transport</param> public RdpeudpDTLSChannel(RdpeudpSocket eudpSocket) { if (eudpSocket == null || eudpSocket.TransMode == TransportMode.Reliable) { throw new NotSupportedException("RdpeudpSocket is null or it is a socket for reliable RDPEUDP connection."); } this.rdpeudpSocket = eudpSocket; this.rdpeudpSocket.Received += ReceiveBytes; isAuthenticated = false; rdpeudpSocket.Disconnected += RdpeudpSocket_Disconnected; receivedBuffer = new List <byte[]>(); toSendBuffer = new List <byte[]>(); if (eudpSocket.AutoHandle) { // Check whether there is packets in unprocessed packet buffer RdpeudpPacket packet = eudpSocket.ExpectPacket(shortWaitTime); if (packet != null) { eudpSocket.ReceivePacket(packet); } } }
/// <summary> /// Expect for a Source Packet. /// </summary> /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param> /// <param name="timeout">Wait time</param> /// <returns></returns> private RdpeudpPacket WaitForSourcePacket(TransportMode udpTransportMode, TimeSpan timeout, uint sequnceNumber = 0) { RdpeudpSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; } DateTime endTime = DateTime.Now + timeout; while (DateTime.Now < endTime) { RdpeudpPacket packet = rdpeudpSocket.ExpectPacket(endTime - DateTime.Now); if (packet != null && packet.fecHeader.uFlags.HasFlag(RDPUDP_FLAG.RDPUDP_FLAG_DATA)) { if (sequnceNumber == 0 || packet.sourceHeader.Value.snSourceStart == sequnceNumber) { return(packet); } } } return(null); }
public void S2_DataTransfer_ClientAckDelay() { 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); this.TestSite.Log.Add(LogEntryKind.Comment, "Send three RDPUDP packets, wait {0} ms between each send"); Thread.Sleep(DelayedACKTimer); this.SendNextValidUdpPacket(transportMode); Thread.Sleep(DelayedACKTimer); this.SendNextValidUdpPacket(transportMode); Thread.Sleep(DelayedACKTimer); this.SendNextValidUdpPacket(transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to send an ACK packet with flag: RDPUDP_FLAG_ACKDELAYED"); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, null, RDPUDP_FLAG.RDPUDP_FLAG_ACKDELAYED); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK with RDPUDP_FLAG_ACKDELAYED flag. Transport mode is {0}", transportMode); } }
private int GetMaxiumPayloadSizeForSourcePacket(int upStreamMtu) { // Create a fake empty RDPEUDP ACK+SOURCE packet. var packet = new RdpeudpPacket(); packet.fecHeader.snSourceAck = 0; packet.fecHeader.uReceiveWindowSize = 0; packet.fecHeader.uFlags = RDPUDP_FLAG.RDPUDP_FLAG_DATA | RDPUDP_FLAG.RDPUDP_FLAG_ACK; var ackVectorHeader = new RDPUDP_ACK_VECTOR_HEADER(); ackVectorHeader.uAckVectorSize = 0; ackVectorHeader.AckVectorElement = null; ackVectorHeader.Padding = null; packet.ackVectorHeader = ackVectorHeader; var sourceHeader = new RDPUDP_SOURCE_PAYLOAD_HEADER(); sourceHeader.snCoded = 0; sourceHeader.snSourceStart = 0; packet.sourceHeader = sourceHeader; var size = PduMarshaler.Marshal(packet).Length; // Maximum payload size = upstream MTU - empty ACK+SOURCE header size. return upStreamMtu - size; }
/// <summary> /// Send a udp packet. /// </summary> /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param> /// <param name="packet">The packet to send.</param> private void SendPacket(TransportMode udpTransportMode, RdpeudpPacket packet) { RdpeudpSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; } rdpeudpSocket.SendPacket(packet); }
/// <summary> /// Get the First valid UDP Source Packet. /// </summary> /// <param name="udpTransportMode"></param> /// <returns></returns> private RdpeudpPacket GetFirstValidUdpPacket(TransportMode udpTransportMode) { byte[] dataToSent = null; RdpeudpPacket firstPacket = null; String certFile; PtfPropUtility.GetPtfPropertyValue(Site, "CertificatePath", out certFile); String certPwd; PtfPropUtility.GetPtfPropertyValue(Site, "CertificatePassword", out certPwd); X509Certificate2 cert = new X509Certificate2(certFile, certPwd); if (udpTransportMode == TransportMode.Reliable) { RdpeudpTLSChannel secChannel = new RdpeudpTLSChannel(rdpeudpSocketR); secChannel.AuthenticateAsServer(cert); RdpeudpPacket packet = rdpeudpSocketR.ExpectPacket(waitTime); if (packet.payload != null) { rdpeudpSocketR.ProcessSourceData(packet); // Process Source Data to make sure ACK Vector created next is correct secChannel.ReceiveBytes(packet.payload); } dataToSent = secChannel.GetDataToSent(waitTime); // Make sure this test packet does not exceed upstream MTU. int maxPayloadsize = GetMaxiumPayloadSizeForSourcePacket(rdpeudpSocketR.UUpStreamMtu); dataToSent = dataToSent.Take(maxPayloadsize).ToArray(); firstPacket = rdpeudpSocketR.CreateSourcePacket(dataToSent); } else { RdpeudpDTLSChannel secChannel = new RdpeudpDTLSChannel(rdpeudpSocketL); secChannel.AuthenticateAsServer(cert); RdpeudpPacket packet = rdpeudpSocketL.ExpectPacket(waitTime); if (packet.payload != null) { rdpeudpSocketL.ProcessSourceData(packet); // Process Source Data to make sure ACK Vector created next is correct secChannel.ReceiveBytes(packet.payload); } dataToSent = secChannel.GetDataToSent(waitTime); // Make sure this test packet does not exceed upstream MTU. int maxPayloadsize = GetMaxiumPayloadSizeForSourcePacket(rdpeudpSocketL.UUpStreamMtu); dataToSent = dataToSent.Take(maxPayloadsize).ToArray(); firstPacket = rdpeudpSocketL.CreateSourcePacket(dataToSent); } return(firstPacket); }
/// <summary> /// Verify an ACK Packet. /// </summary> /// <param name="ackPacket">The ACK packet.</param> private void VerifyACKPacket(RdpeudpPacket ackPacket) { if (ackPacket == null) { this.Site.Assert.Fail("The ACK Packet should not be null!"); } if ((ackPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_ACK) == 0) { this.Site.Assert.Fail("The RDPUDP_FLAG_ACK flag MUST be set in ACK packet!"); } }
public void S2_DataTransfer_SequenceNumberWrapAround() { TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; CheckPlatformCompatibility(ref transportModeArray); CheckSecurityProtocolForMultitransport(); Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); foreach (TransportMode transportMode in transportModeArray) { DoUntilSucceed(() => { 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); return(this.EstablishRdpemtConnection(transportMode, waitTime)); }, this.waitTime * 5, TimeSpan.FromSeconds(0.5), "RDPEMT tunnel creation failed"); 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_CongestionControlTest_ClientReceiveData() { TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; CheckPlatformCompatibility(ref transportModeArray); CheckSecurityProtocolForMultitransport(); Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); foreach (TransportMode transportMode in transportModeArray) { DoUntilSucceed(() => { 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); return(this.EstablishRdpemtConnection(transportMode, waitTime)); }, this.waitTime * 5, TimeSpan.FromSeconds(0.5), "RDPEMT tunnel creation failed"); 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 another three RDPUDP packet."); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); // Expect an ACK packet with RDPUDP_FLAG_SYN flag. this.TestSite.Log.Add(LogEntryKind.Comment, "expect an ACK packet with RDPUDP_FLAG_SYN flag."); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, null, RDPUDP_FLAG.RDPUDP_FLAG_CN, 0); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK packet with RDPUDP_FLAG_SYN flag, transport mode is {0}", transportMode); RdpeudpPacket packet = this.GetNextValidUdpPacket(transportMode); packet.fecHeader.uFlags = packet.fecHeader.uFlags | RDPUDP_FLAG.RDPUDP_FLAG_CWR; this.SendPacket(transportMode, packet); // Expect an ACK packet without RDPUDP_FLAG_SYN flag. this.TestSite.Log.Add(LogEntryKind.Comment, "expect an ACK packet without RDPUDP_FLAG_SYN flag."); ackpacket = WaitForACKPacket(transportMode, waitTime, null, 0, RDPUDP_FLAG.RDPUDP_FLAG_CN); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK packet without RDPUDP_FLAG_SYN flag, transport mode is {0}", transportMode); } }
/// <summary> /// Verify SYN packet. /// </summary> /// <param name="synPacket">The SYN packet.</param> /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param> private void VerifySYNPacket(RdpeudpPacket synPacket, TransportMode udpTransportMode) { if (synPacket == null) { this.Site.Assert.Fail("The SYN Packet should not be null!"); } if (synPacket.fecHeader.snSourceAck != uint.MaxValue) { this.Site.Assert.Fail("The snSourceAck variable MUST be set to -1 (max value of uint)!"); } if ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYN) == 0) { this.Site.Assert.Fail("The RDPUDP_FLAG_SYN flag MUST be set in SYN packet!"); } if (udpTransportMode == TransportMode.Reliable) { if ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYNLOSSY) == RDPUDP_FLAG.RDPUDP_FLAG_SYNLOSSY) { this.Site.Assert.Fail("The RDPUDP_FLAG_SYNLOSSY flag MUST not be set when choose reliable UDP connection!"); } } else { if ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYNLOSSY) == 0) { this.Site.Assert.Fail("The RDPUDP_FLAG_SYNLOSSY flag MUST be set When choose lossy UDP connection!"); } } if (synPacket.SynData == null) { this.Site.Assert.Fail("The SYN Packet should contain a RDPUDP_SYNDATA_PAYLOAD structure!"); } if (synPacket.SynData.Value.uUpStreamMtu > 1232 || synPacket.SynData.Value.uUpStreamMtu < 1132) { this.Site.Assert.Fail("The uUpStreamMtu field MUST be set to a value in the range of 1132 to 1232."); } if (synPacket.SynData.Value.uDownStreamMtu > 1232 || synPacket.SynData.Value.uDownStreamMtu < 1132) { this.Site.Assert.Fail("The uDownStreamMtu field MUST be set to a value in the range of 1132 to 1232."); } }
/// <summary> /// Get the next valid rdpeudp packet. /// </summary> /// <param name="udpTransportMode">Transport mode: reliable or Lossy.</param> /// <returns>The next valid rdpeudp packet.</returns> private RdpeudpPacket GetNextValidUdpPacket(TransportMode udpTransportMode, byte[] data = null) { /*This function is used to get a valid rdpeudp packet. * Using rdpeudpSocket.LossPacket flag to control whether the socket send the packet. * First set rdpeudpSocket.LossPacket to true and send a tunnal Data, the socket will store the next packet(RDPEUDP socket which contains the encrypted tunnel data) and doesn't send it. * Then get the stored packet and return it. */ RdpemtServer rdpemtServer = rdpemtServerR; RdpeudpSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpemtServer = rdpemtServerL; rdpeudpSocket = rdpeudpSocketL; } if (data == null) { data = new byte[1000]; } RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(data, null); byte[] unEncryptData = PduMarshaler.Marshal(tunnelData); byte[] encryptData = null; if (udpTransportMode == TransportMode.Reliable) { RdpeudpTLSChannel secChannel = rdpemtServer.SecureChannel as RdpeudpTLSChannel; encryptData = secChannel.Encrypt(unEncryptData); } else { RdpeudpDTLSChannel secChannel = rdpemtServer.SecureChannel as RdpeudpDTLSChannel; List <byte[]> encryptDataList = secChannel.Encrypt(unEncryptData); if (encryptDataList != null && encryptDataList.Count > 0) { encryptData = encryptDataList[0]; } } RdpeudpPacket packet = rdpeudpSocket.CreateSourcePacket(encryptData); return(packet); }
/// <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> /// Create invalid SYN and ACK Packet /// </summary> /// <param name="udpTransportMode">Transport mode: reliable or lossy</param> /// <param name="invalidType">Invalid type</param> /// <param name="initSequenceNumber">init sequence</param> /// <returns></returns> private RdpeudpPacket CreateInvalidSynAndACKPacket(TransportMode udpTransportMode, SynAndAck_InvalidType invalidType, uint?initSequenceNumber = null) { RdpeudpServerSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; } // Create the SYN and ACK packet. RdpeudpPacket SynAndAckPacket = new RdpeudpPacket(); SynAndAckPacket.fecHeader.snSourceAck = rdpeudpSocket.SnSourceAck; SynAndAckPacket.fecHeader.uReceiveWindowSize = rdpeudpSocket.UReceiveWindowSize; SynAndAckPacket.fecHeader.uFlags = RDPUDP_FLAG.RDPUDP_FLAG_SYN | RDPUDP_FLAG.RDPUDP_FLAG_ACK; RDPUDP_SYNDATA_PAYLOAD SynPayload = rdpeudpSocket.CreateSynData(initSequenceNumber); switch (invalidType) { case SynAndAck_InvalidType.LargerUpStreamMtu: SynPayload.uUpStreamMtu = 1232 + 1; break; case SynAndAck_InvalidType.SamllerUpStreamMtu: SynPayload.uUpStreamMtu = 1132 - 1; break; case SynAndAck_InvalidType.LargerDownStreamMtu: SynPayload.uDownStreamMtu = 1232 + 1; break; case SynAndAck_InvalidType.SamllerDownStreamMtu: SynPayload.uDownStreamMtu = 1132 - 1; break; } SynAndAckPacket.SynData = SynPayload; return(SynAndAckPacket); }
/// <summary> /// Send SYN and ACK packet. /// </summary> /// <param name="udpTransportMode">Transport mode: Reliable or Lossy</param> /// <param name="invalidType">invalid type</param> public void SendSynAndAckPacket(TransportMode udpTransportMode, SynAndAck_InvalidType invalidType, uint? initSequenceNumber = null, uUdpVer_Values? uUdpVer = null) { RdpeudpServerSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; } if (invalidType == SynAndAck_InvalidType.None) { // If invalid type is None, send the packet directly. rdpeudpSocket.SendSynAndAckPacket(initSequenceNumber, uUdpVer); return; } // Create the SYN and ACK packet first. RdpeudpPacket SynAndAckPacket = CreateInvalidSynAndACKPacket(udpTransportMode, invalidType, initSequenceNumber); rdpeudpSocket.SendPacket(SynAndAckPacket); }
public void S2_DataTransfer_CongestionControlTest_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, "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 another three RDPUDP packet."); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); this.SendNextValidUdpPacket(transportMode); // Expect an ACK packet with RDPUDP_FLAG_SYN flag. this.TestSite.Log.Add(LogEntryKind.Comment, "expect an ACK packet with RDPUDP_FLAG_SYN flag."); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, null, RDPUDP_FLAG.RDPUDP_FLAG_CN, 0); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK packet with RDPUDP_FLAG_SYN flag, transport mode is {0}", transportMode); RdpeudpPacket packet = this.GetNextValidUdpPacket(transportMode); packet.fecHeader.uFlags = packet.fecHeader.uFlags | RDPUDP_FLAG.RDPUDP_FLAG_CWR; this.SendPacket(transportMode, packet); // Expect an ACK packet without RDPUDP_FLAG_SYN flag. this.TestSite.Log.Add(LogEntryKind.Comment, "expect an ACK packet without RDPUDP_FLAG_SYN flag."); ackpacket = WaitForACKPacket(transportMode, waitTime, null, 0, RDPUDP_FLAG.RDPUDP_FLAG_CN); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK packet without RDPUDP_FLAG_SYN flag, transport mode is {0}", transportMode); } }
public void S2_DataTransfer_ClientAckDelay() { TransportMode[] transportModeArray = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; CheckPlatformCompatibility(ref transportModeArray); CheckSecurityProtocolForMultitransport(); Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); foreach (TransportMode transportMode in transportModeArray) { DoUntilSucceed(() => { 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); return(this.EstablishRdpemtConnection(transportMode, waitTime)); }, this.waitTime * 5, TimeSpan.FromSeconds(0.5), "RDPEMT tunnel creation failed"); this.TestSite.Log.Add(LogEntryKind.Comment, "Send three RDPUDP packets, wait {0} ms between each send"); Thread.Sleep(DelayedACKTimer); this.SendNextValidUdpPacket(transportMode); Thread.Sleep(DelayedACKTimer); this.SendNextValidUdpPacket(transportMode); Thread.Sleep(DelayedACKTimer); this.SendNextValidUdpPacket(transportMode); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect RDP client to send an ACK packet with flag: RDPUDP_FLAG_ACKDELAYED"); RdpeudpPacket ackpacket = WaitForACKPacket(transportMode, waitTime, null, RDPUDP_FLAG.RDPUDP_FLAG_ACKDELAYED); Site.Assert.IsNotNull(ackpacket, "Client should send an ACK with RDPUDP_FLAG_ACKDELAYED flag. Transport mode is {0}", transportMode); } }
/// <summary> /// Constructor /// </summary> /// <param name="eudpSocket">A RdpeudpSocket used for transport</param> public RdpeudpTLSChannel(RdpeudpSocket eudpSocket) { if (eudpSocket == null || eudpSocket.TransMode == TransportMode.Lossy) { throw new NotSupportedException("RdpeudpSocket is null or it is a socket for Lossy RDPEUDP connection."); } this.rdpeudpSocket = eudpSocket; this.rdpeudpSocket.Received += ReceiveBytes; innerStream = new SSLInnerStream(); isAuthenticated = false; if (eudpSocket.AutoHandle) { // Check whether there is packets in unprocessed packet buffer RdpeudpPacket packet = eudpSocket.ExpectPacket(shortWaitTime); if (packet != null) { eudpSocket.ReceivePacket(packet); } } }
/// <summary> /// Get the First valid UDP Source Packet. /// </summary> /// <param name="udpTransportMode"></param> /// <returns></returns> private RdpeudpPacket GetFirstValidUdpPacket(TransportMode udpTransportMode) { byte[] dataToSent = null; RdpeudpPacket firstPacket = null; String certFile = this.Site.Properties["CertificatePath"]; String certPwd = this.Site.Properties["CertificatePassword"]; X509Certificate2 cert = new X509Certificate2(certFile, certPwd); if (udpTransportMode == TransportMode.Reliable) { RdpeudpTLSChannel secChannel = new RdpeudpTLSChannel(rdpeudpSocketR); secChannel.AuthenticateAsServer(cert); RdpeudpPacket packet = rdpeudpSocketR.ExpectPacket(waitTime); if (packet.payload != null) { rdpeudpSocketR.ProcessSourceData(packet); // Process Source Data to makesure ACK Vector created next is correct secChannel.ReceiveBytes(packet.payload); } dataToSent = secChannel.GetDataToSent(waitTime); firstPacket = rdpeudpSocketR.CreateSourcePacket(dataToSent); } else { RdpeudpDTLSChannel secChannel = new RdpeudpDTLSChannel(rdpeudpSocketL); secChannel.AuthenticateAsServer(cert); RdpeudpPacket packet = rdpeudpSocketL.ExpectPacket(waitTime); if (packet.payload != null) { rdpeudpSocketL.ProcessSourceData(packet); // Process Source Data to makesure ACK Vector created next is correct secChannel.ReceiveBytes(packet.payload); } dataToSent = secChannel.GetDataToSent(waitTime); firstPacket = rdpeudpSocketL.CreateSourcePacket(dataToSent); } return(firstPacket); }
public void S2_DataTransfer_RetransmitTest_ClientRetransmit() { // Record the sequenceNumber of the lost source packet. uint sequenceNumberForLossPacket = 0; ushort receiveWindowSize = 0; Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); this.TestSite.Log.Add(LogEntryKind.Comment, "Create a reliable UDP connection."); this.EstablishUDPConnection(TransportMode.Reliable, waitTime, true); this.TestSite.Log.Add(LogEntryKind.Comment, "Send the first RDPEUDP Source packet, but not acknowledge the receipt of the first source packet from client."); RdpeudpPacket packet = this.GetFirstValidUdpPacket(TransportMode.Reliable); #region Change packet.ackVectorHeader To Not Acknowledge The Receipt RDPUDP_ACK_VECTOR_HEADER ackVectorHeader = new RDPUDP_ACK_VECTOR_HEADER(); ackVectorHeader.AckVectorElement = null; ackVectorHeader.uAckVectorSize = 0; packet.ackVectorHeader = ackVectorHeader; sequenceNumberForLossPacket = packet.fecHeader.snSourceAck; receiveWindowSize = packet.fecHeader.uReceiveWindowSize; packet.fecHeader.snSourceAck--; #endregion Change packet.ackVectorHeader To Not Acknowledge The Receipt this.SendPacket(TransportMode.Reliable, packet); this.TestSite.Log.Add(LogEntryKind.Comment, "Wait for 200 ms so as to fire the retransmit timer."); Thread.Sleep(this.RetransmitTimer); this.TestSite.Log.Add(LogEntryKind.Comment, "Wait for the client to resend the lost packet."); RdpeudpPacket receivedPacket = this.WaitForSourcePacket(TransportMode.Reliable, waitTime, sequenceNumberForLossPacket); Site.Assert.IsNotNull(receivedPacket, "Client should resend the packet if not receiving an ACK for a specified time."); }
/// <summary> /// Establish a UDP connection. /// </summary> /// <param name="udpTransportMode">Transport mode: Reliable or Lossy.</param> /// <param name="timeout">Wait time.</param> /// <param name="verifyPacket">Whether verify the received packet.</param> /// <returns>The accepted socket.</returns> private RdpeudpSocket EstablishUDPConnection(TransportMode udpTransportMode, TimeSpan timeout, bool verifyPacket = false, bool autoHanlde = false) { // Start UDP listening. if (rdpeudpServer == null) { rdpeudpServer = new RdpeudpServer((IPEndPoint)this.rdpbcgrAdapter.SessionContext.LocalIdentity, autoHanlde); } if (!rdpeudpServer.Running) { rdpeudpServer.Start(); } // Send a Server Initiate Multitransport Request PDU. byte[] securityCookie = new byte[16]; Random rnd = new Random(); rnd.NextBytes(securityCookie); Multitransport_Protocol_value requestedProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (udpTransportMode == TransportMode.Lossy) { requestedProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } this.rdpbcgrAdapter.SendServerInitiateMultitransportRequestPDU(++this.multitransportRequestId, requestedProtocol, securityCookie); // Create a UDP socket. RdpeudpServerSocket rdpudpSocket = rdpeudpServer.CreateSocket(((IPEndPoint)this.rdpbcgrAdapter.SessionContext.Identity).Address, udpTransportMode, timeout); if (rdpudpSocket == null) { this.Site.Assert.Fail("Failed to create a UDP socket for the Client : {0}", ((IPEndPoint)this.rdpbcgrAdapter.SessionContext.Identity).Address); } if (udpTransportMode == TransportMode.Reliable) { this.rdpeudpSocketR = rdpudpSocket; } else { this.rdpeudpSocketL = rdpudpSocket; } // Expect a SYN packet. RdpeudpPacket synPacket = rdpudpSocket.ExpectSynPacket(timeout); if (synPacket == null) { this.Site.Assert.Fail("Time out when waiting for the SYN packet"); } // Verify the SYN packet. if (verifyPacket) { VerifySYNPacket(synPacket, udpTransportMode); } // Send a SYN and ACK packet. SendSynAndAckPacket(udpTransportMode, SynAndAck_InvalidType.None, initSequenceNumber); // Expect an ACK packet or ACK and Source Packet. RdpeudpPacket ackPacket = rdpudpSocket.ExpectACKPacket(timeout); if (ackPacket == null) { this.Site.Assert.Fail("Time out when waiting for the ACK packet to response the ACK and SYN packet"); } // Verify the ACK packet. if (verifyPacket) { VerifyACKPacket(ackPacket); } // If the packet is an ACK and Source Packet, add the source packet to the un-processed packet. if (ackPacket.fecHeader.uFlags.HasFlag(RDPUDP_FLAG.RDPUDP_FLAG_DATA)) { byte[] bytes = PduMarshaler.Marshal(ackPacket, false); RdpeudpBasePacket stackpacket = new RdpeudpBasePacket(bytes); rdpudpSocket.ReceivePacket(stackpacket); } rdpudpSocket.Connected = true; return(rdpudpSocket); }
/// <summary> /// Verify SYN packet. /// </summary> /// <param name="synPacket">The SYN packet.</param> /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param> private void VerifySYNPacket(RdpeudpPacket synPacket, TransportMode udpTransportMode) { if (synPacket == null) { this.Site.Assert.Fail("The SYN Packet should not be null!"); } if (synPacket.fecHeader.snSourceAck != uint.MaxValue) { this.Site.Assert.Fail("The snSourceAck variable MUST be set to -1 (max value of uint)!"); } if ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYN) == 0) { this.Site.Assert.Fail("The RDPUDP_FLAG_SYN flag MUST be set in SYN packet!"); } if (udpTransportMode == TransportMode.Reliable) { if ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYNLOSSY) == RDPUDP_FLAG.RDPUDP_FLAG_SYNLOSSY) { this.Site.Assert.Fail("The RDPUDP_FLAG_SYNLOSSY flag MUST not be set when choose reliable UDP connection!"); } } else { if ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYNLOSSY) == 0) { this.Site.Assert.Fail("The RDPUDP_FLAG_SYNLOSSY flag MUST be set When choose lossy UDP connection!"); } } if (synPacket.SynData == null) { this.Site.Assert.Fail("The SYN Packet should contain a RDPUDP_SYNDATA_PAYLOAD structure!"); } if (synPacket.SynData.Value.uUpStreamMtu > 1232 || synPacket.SynData.Value.uUpStreamMtu < 1132) { this.Site.Assert.Fail("The uUpStreamMtu field MUST be set to a value in the range of 1132 to 1232."); } if (synPacket.SynData.Value.uDownStreamMtu > 1232 || synPacket.SynData.Value.uDownStreamMtu < 1132) { this.Site.Assert.Fail("The uDownStreamMtu field MUST be set to a value in the range of 1132 to 1232."); } // The RDPUDP_FLAG_SYNEX flag and RDPUDP_SYNDATAEX_PAYLOAD structure should appear at the same time. if ((synPacket.SynDataEx == null) ^ ((synPacket.fecHeader.uFlags & RDPUDP_FLAG.RDPUDP_FLAG_SYNEX) == 0)) { this.Site.Assert.Fail("Section 3.1.5.1.1: The RDPUDP_FLAG_SYNEX flag MUST be set only when the RDPUDP_SYNDATAEX_PAYLOAD structure is included. Section 3.1.5.1.1: The RDPUDP_SYNEX_PAYLOAD structure MUST be appended to the UDP datagram if the RDPUDP_FLAG_SYNEX flag is set in uFlags."); } //Section 3.1.5.1.1: Not appending RDPUDP_SYNDATAEX_PAYLOAD structure implies that RDPUDP_PROTOCOL_VERSION_1 is the highest protocol version supported. if (synPacket.SynDataEx == null) { this.clientUUdpVer = uUdpVer_Values.RDPUDP_PROTOCOL_VERSION_1; this.clientRdpudpVerfionInfoValidFlag = null; } else { this.clientUUdpVer = synPacket.SynDataEx.Value.uUdpVer; this.clientRdpudpVerfionInfoValidFlag = synPacket.SynDataEx.Value.uSynExFlags; //Section 3.1.5.1.1: The RDPUDP_VERSION_INFO_VALID flag MUST be set only if the structure contains a valid RDP-UDP protocol version. if (synPacket.SynDataEx.Value.uSynExFlags.HasFlag(uSynExFlags_Values.RDPUDP_VERSION_INFO_VALID) && ((int)synPacket.SynDataEx.Value.uUdpVer & 0xfffc) != 0) { this.Site.Assert.Fail("Section 3.1.5.1.1: The RDPUDP_VERSION_INFO_VALID flag MUST be set only if the structure contains a valid RDP-UDP protocol version"); } } }
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); } }
/// <summary> /// Establish a UDP connection. /// </summary> /// <param name="udpTransportMode">Transport mode: Reliable or Lossy.</param> /// <param name="timeout">Wait time.</param> /// <param name="verifyPacket">Whether verify the received packet.</param> /// <returns>The accepted socket.</returns> private RdpeudpSocket EstablishUDPConnection(TransportMode udpTransportMode, TimeSpan timeout, bool verifyPacket = false, bool autoHanlde = false, uUdpVer_Values? uUdpVer = null) { // Start UDP listening. if (rdpeudpServer == null) { rdpeudpServer = new RdpeudpServer((IPEndPoint)this.rdpbcgrAdapter.SessionContext.LocalIdentity, autoHanlde); rdpeudpServer.UnhandledExceptionReceived += (ex) => { Site.Log.Add(LogEntryKind.Debug, $"Unhandled exception from RdpeudpServer: {ex}"); }; } if (!rdpeudpServer.Running) rdpeudpServer.Start(); // Send a Server Initiate Multitransport Request PDU. byte[] securityCookie = new byte[16]; Random rnd = new Random(); rnd.NextBytes(securityCookie); Multitransport_Protocol_value requestedProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (udpTransportMode == TransportMode.Lossy) { requestedProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } this.rdpbcgrAdapter.SendServerInitiateMultitransportRequestPDU(++this.multitransportRequestId, requestedProtocol, securityCookie); // Create a UDP socket. RdpeudpServerSocket rdpudpSocket = rdpeudpServer.CreateSocket(((IPEndPoint)this.rdpbcgrAdapter.SessionContext.Identity).Address, udpTransportMode, timeout); if (rdpudpSocket == null) { this.Site.Assert.Fail("Failed to create a UDP socket for the Client : {0}", ((IPEndPoint)this.rdpbcgrAdapter.SessionContext.Identity).Address); } if (udpTransportMode == TransportMode.Reliable) { this.rdpeudpSocketR = rdpudpSocket; } else { this.rdpeudpSocketL = rdpudpSocket; } // Expect a SYN packet. RdpeudpPacket synPacket = rdpudpSocket.ExpectSynPacket(timeout); if (synPacket == null) { this.Site.Assert.Fail("Time out when waiting for the SYN packet"); } // Verify the SYN packet. if (verifyPacket) { VerifySYNPacket(synPacket, udpTransportMode); } // Send a SYN and ACK packet. if (this.clientRdpudpVerfionInfoValidFlag == uSynExFlags_Values.RDPUDP_VERSION_INFO_VALID) { //Section 3.1.5.1.3: The uUdpVer field MUST be set to the highest RDP-UDP protocol version supported by both endpoints. uUdpVer = uUdpVer > this.clientUUdpVer ? this.clientUUdpVer : uUdpVer; SendSynAndAckPacket(udpTransportMode, SynAndAck_InvalidType.None, initSequenceNumber, uUdpVer); } else if (this.clientRdpudpVerfionInfoValidFlag == uSynExFlags_Values.None) { //Section 3.1.5.1.3: The highest version supported by both endpoints, which is RDPUDP_PROTOCOL_VERSION_1 if either this packet or the SYN packet does not specify a version, is the version that MUST be used by both endpoints. SendSynAndAckPacket(udpTransportMode, SynAndAck_InvalidType.None, initSequenceNumber, uUdpVer_Values.RDPUDP_PROTOCOL_VERSION_1); } else { //Section 3.1.5.1.3: The RDPUDP_SYNEX_PAYLOAD structure (section 2.2.2.9) SHOULD only be present if it is also present in the received SYN packet. // When the SendSynAndAckPacket(udpTransportMode, SynAndAck_InvalidType.None, initSequenceNumber, null); } // Expect an ACK packet or ACK and Source Packet. RdpeudpPacket ackPacket = rdpudpSocket.ExpectACKPacket(timeout); if (ackPacket == null) { this.Site.Assert.Fail("Time out when waiting for the ACK packet to response the ACK and SYN packet"); } // Verify the ACK packet. if (verifyPacket) { VerifyACKPacket(ackPacket); } // If the packet is an ACK and Source Packet, add the source packet to the un-processed packet. if (ackPacket.fecHeader.uFlags.HasFlag(RDPUDP_FLAG.RDPUDP_FLAG_DATA)) { byte[] bytes = PduMarshaler.Marshal(ackPacket, false); RdpeudpBasePacket stackpacket = new RdpeudpBasePacket(bytes); rdpudpSocket.ReceivePacket(stackpacket); } rdpudpSocket.Connected = true; return rdpudpSocket; }