/// <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> /// Used to establish a RDPEMT connection. /// </summary> /// <param name="udpTransportMode">Transport Mode: Reliable or Lossy.</param> /// <param name="timeout">Wait time.</param> /// <returns>true,false.</returns> private bool EstablishRdpemtConnection(TransportMode udpTransportMode, TimeSpan timeout) { bool pass = true; RdpeudpServerSocket rdpeudpSocket = rdpeudpSocketR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; } if (!rdpeudpSocket.AutoHandle) { rdpeudpSocket.AutoHandle = true; } String certFile; PtfPropUtility.GetPtfPropertyValue(Site, "CertificatePath", out certFile); String certPwd; PtfPropUtility.GetPtfPropertyValue(Site, "CertificatePassword", out certPwd); X509Certificate2 cert = new X509Certificate2(certFile, certPwd); RdpemtServer rdpemtServer = new RdpemtServer(rdpeudpSocket, cert); uint receivedRequestId; byte[] receivedSecurityCookie; if (!rdpemtServer.ExpectConnect(waitTime, out receivedRequestId, out receivedSecurityCookie)) { pass = false; } rdpeudpSocket.AutoHandle = false; if (udpTransportMode == TransportMode.Reliable) { rdpemtServerR = rdpemtServer; } else { rdpemtServerL = rdpemtServer; } if (!pass) { this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} RDPEMT connection failed, stop rdpeudpServer and close socket connection and retry.", udpTransportMode); rdpeudpServer.Stop(); rdpeudpServer = null; if (udpTransportMode == TransportMode.Reliable) { rdpeudpSocketR.Close(); rdpeudpSocketR = null; } else { rdpeudpSocketL.Close(); rdpeudpSocketL = null; } } return(pass); }
/// <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; }
/// <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); }