public void S2_AutoDetect_RTTMeasure_Lossy() { CheckPlatformCompatibility(TransportMode.Lossy); ushort sequenceNumber = 1; Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); var mode = TransportMode.Lossy; Multitransport_Protocol_value protocolValue = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} UDP connection.", mode); this.EstablishUDPConnection(mode, waitTime); this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} RDPEMT connection.", mode); this.EstablishRdpemtConnection(mode, waitTime, true); this.TestSite.Log.Add(LogEntryKind.Comment, "Send a RTT Measure Request"); this.SendTunnelDataPdu_RTTMeasureRequest(protocolValue, ++sequenceNumber); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect a RTT Measure Response"); this.WaitForAndCheckTunnelDataPdu_RTTResponse(protocolValue, sequenceNumber, timeout); this.TestSite.Log.Add(LogEntryKind.Comment, "Send a Network Characteristics Result"); this.SendTunnelDataPdu_NetcharResult(protocolValue, sequenceNumber); }
public void S2_AutoDetect_RTTMeasure() { ushort sequenceNumber = 1; TransportMode[] transportModeList = new TransportMode[] { TransportMode.Reliable, TransportMode.Lossy }; Site.Log.Add(LogEntryKind.Debug, "Establishing RDP connection ..."); StartRDPConnection(); foreach (TransportMode mode in transportModeList) { Multitransport_Protocol_value protocolValue = (mode == TransportMode.Reliable)?Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR:Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} UDP connection.", mode); this.EstablishUDPConnection(mode, waitTime); this.TestSite.Log.Add(LogEntryKind.Comment, "Create a {0} RDPEMT connection.", mode); this.EstablishRdpemtConnection(mode, waitTime, true); this.TestSite.Log.Add(LogEntryKind.Comment, "Send a RTT Measure Request"); this.SendTunnelDataPdu_RTTMeasureRequest(protocolValue, ++sequenceNumber); this.TestSite.Log.Add(LogEntryKind.Comment, "Expect a RTT Measure Response"); this.WaitForAndCheckTunnelDataPdu_RTTResponse(protocolValue, sequenceNumber, timeout); this.TestSite.Log.Add(LogEntryKind.Comment, "Send a Network Characteristics Result"); this.SendTunnelDataPdu_NetcharResult(protocolValue, sequenceNumber); } }
/// <summary> /// Constructor /// </summary> /// <param name="connectedRdpServer"></param> /// <param name="context"></param> /// <param name="transportType"></param> public Rdpemt_DVCServerTransport(RdpbcgrServer connectedRdpServer, RdpbcgrServerSessionContext context, DynamicVC_TransportType transportType) { this.serverSessionContext = context; this.rdpbcgrServer = connectedRdpServer; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } if (!serverSessionContext.IsClientMultitransportChannelDataRecieved) { throw new NotSupportedException("This RDP connection doesn't support multiple transport!"); } try { EstablishTransportConnection(); } catch (Exception) { // Ensure resource can be released properly if exception occurred in Constructor Dispose(); // Not suppress the exception, transfer the error to test result. throw; } decoder = new ServerDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
/// <summary> /// Send a Tunnel Data PDU with RDP_NETCHAR_RESULT in its subheader /// </summary> /// <param name="requestedProtocol"></param> /// <param name="sequenceNumber"></param> private void SendTunnelDataPdu_NetcharResult(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber) { autoDetectedBaseRTT = (uint)(rttDataStore.responseTime - rttDataStore.requestTime).Milliseconds; autoDetectedAverageRTT = (uint)(rttDataStore.responseTime - rttDataStore.requestTime).Milliseconds; if (bwDataStore.timeDelta != 0) { autoDetectedBandwidth = (bwDataStore.byteCount * 8) / bwDataStore.timeDelta; } RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { rdpemtServer = rdpemtServerL; } RDP_NETCHAR_RESULT netResult = RdpbcgrUtility.GenerateNetworkCharacteristicsResult(AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT, sequenceNumber, autoDetectedBaseRTT, autoDetectedBandwidth, autoDetectedAverageRTT); byte[] reqData = rdpbcgrServer.EncodeNetworkDetectionRequest(netResult, true); List <byte[]> subHdDataList = new List <byte[]>(); subHdDataList.Add(reqData); RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList); rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <summary> /// Construcotr /// </summary> /// <param name="clientSessionContext"></param> /// <param name="transportType"></param> public Rdpemt_DVCClientTransport(RdpbcgrClientContext clientSessionContext, DynamicVC_TransportType transportType) { this.clientSessionContext = clientSessionContext; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } decoder = new ClientDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
/// <summary> /// Construcotr /// </summary> /// <param name="clientSessionContext"></param> /// <param name="transportType"></param> public Rdpemt_DVCClientTransport(RdpbcgrClientContext clientSessionContext, DynamicVC_TransportType transportType) { this.clientSessionContext = clientSessionContext; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } EstablishTransportConnection(); decoder = new ClientDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
/// <summary> /// Establish a UDP connection /// </summary> /// <param name="udpTransportMode">Transport mode: Reliable or Lossy</param> /// <param name="timeout">wait time</param> /// <returns>The accepted socket</returns> private void EstablishUDPConnection(TransportMode udpTransportMode, TimeSpan timeout) { //Start UDP listening if (rdpeudpServer == null) { rdpeudpServer = new RdpeudpServer((IPEndPoint)this.rdpbcgrAdapter.SessionContext.LocalIdentity, true); 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); this.requestIdList.Add(this.multitransportRequestId); this.securityCookieList.Add(securityCookie); //create a UDP socket RdpeudpSocket rdpudpSocket = rdpeudpServer.Accept(((IPEndPoint)this.rdpbcgrAdapter.SessionContext.Identity).Address, udpTransportMode, timeout); if (udpTransportMode == TransportMode.Reliable) { this.rdpeudpSocketR = rdpudpSocket; } else { this.rdpeudpSocketL = rdpudpSocket; } }
/// <summary> /// Constructor /// </summary> /// <param name="connectedRdpServer"></param> /// <param name="context"></param> /// <param name="transportType"></param> public Rdpemt_DVCServerTransport(RdpbcgrServer connectedRdpServer, RdpbcgrServerSessionContext context, DynamicVC_TransportType transportType) { this.serverSessionContext = context; this.rdpbcgrServer = connectedRdpServer; this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECR; if (transportType == DynamicVC_TransportType.RDP_UDP_Lossy) { this.transportProtocol = Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL; } if (!serverSessionContext.IsClientMultitransportChannelDataRecieved) { throw new NotSupportedException("This RDP connection doesn't support multiple transport!"); } EstablishTransportConnection(); decoder = new ServerDecodingPduBuilder(); pduBuilder = new PduBuilder(); }
/// <summary> /// Send a Tunnel Data PDU with RTT Measure Request in its subheader /// </summary> /// <param name="udpTransportMode">Transport Mode: Reliable or Lossy</param> private void SendTunnelDataPdu_RTTMeasureRequest(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber) { AUTO_DETECT_REQUEST_TYPE requestType = AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME; RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { rdpemtServer = rdpemtServerL; } RDP_RTT_REQUEST RTTRequest = RdpbcgrUtility.GenerateRTTMeasureRequest(requestType, sequenceNumber); byte[] reqData = rdpbcgrServer.EncodeNetworkDetectionRequest(RTTRequest, true); List <byte[]> subHdDataList = new List <byte[]>(); subHdDataList.Add(reqData); RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList); rttDataStore.requestTime = DateTime.Now; rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <summary> /// Send a Tunnel Data PDU with RDP_BW_STOP in its subheader /// </summary> /// <param name="requestedProtocol"></param> /// <param name="sequenceNumber"></param> private void SendTunnelDataPdu_BWStop(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber) { AUTO_DETECT_REQUEST_TYPE requestType = AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_RELIABLEUDP; RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { requestType = AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_LOSSYUDP; rdpemtServer = rdpemtServerL; } RDP_BW_STOP bwStop = RdpbcgrUtility.GenerateBandwidthMeasureStop(requestType, sequenceNumber); byte[] reqData = rdpbcgrServer.EncodeNetworkDetectionRequest(bwStop, true); List <byte[]> subHdDataList = new List <byte[]>(); subHdDataList.Add(reqData); RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList); rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <summary> /// Send Tunnel Create Request PDU to server. /// </summary> /// <param name="negativeType">The negative type want to test.</param> /// <param name="requestedProtocol">The request multitransport protocol.</param> public void SendTunnelCreateRequest(NegativeType negativeType, Multitransport_Protocol_value requestedProtocol) { var serverInitiateMultitransportRequestPDU = serverInitiateMultitransportRequestPDUs[requestedProtocol]; uint requestId = serverInitiateMultitransportRequestPDU.requestId; var securityCookie = serverInitiateMultitransportRequestPDU.securityCookie; bool modifyRequestID = false; bool modifySecurityCookie = false; switch (negativeType) { case NegativeType.TunnelCreateRequest_InvalidRequestID: modifyRequestID = true; break; case NegativeType.TunnelCreateRequest_InvalidSecurityCookie: modifySecurityCookie = true; break; case NegativeType.TunnelCreateRequest_InvalidRequestIDAndSecurityCookie: modifyRequestID = true; modifySecurityCookie = true; break; } if (modifyRequestID) { requestId = (uint)RequestID_Values.Invalid; } if (modifySecurityCookie) { securityCookie = securityCookie.Select(x => (byte)~x).ToArray(); } var createTunnelCreateRequestPDU = rdpemtClients[requestedProtocol].CreateTunnelCreateRequest(requestId, securityCookie); rdpemtClients[requestedProtocol].SendRdpemtPacket(createTunnelCreateRequestPDU); }
/// <summary> /// Send a Tunnel Data PDU with RDP_NETCHAR_RESULT in its subheader /// </summary> /// <param name="requestedProtocol"></param> /// <param name="sequenceNumber"></param> private void SendTunnelDataPdu_NetcharResult(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber) { autoDetectedBaseRTT = (uint) (rttDataStore.responseTime - rttDataStore.requestTime).Milliseconds; autoDetectedAverageRTT = (uint)(rttDataStore.responseTime - rttDataStore.requestTime).Milliseconds; if (bwDataStore.timeDelta != 0) { autoDetectedBandwidth = (bwDataStore.byteCount * 8) / bwDataStore.timeDelta; } RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { rdpemtServer = rdpemtServerL; } RDP_NETCHAR_RESULT netResult = RdpbcgrUtility.GenerateNetworkCharacteristicsResult(AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT, sequenceNumber, autoDetectedBaseRTT, autoDetectedBandwidth, autoDetectedAverageRTT); byte[] reqData = rdpbcgrServer.EncodeNetworkDetectionRequest(netResult, true); List<byte[]> subHdDataList = new List<byte[]>(); subHdDataList.Add(reqData); RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList); rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <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> /// Send a Tunnel Data PDU with RDP_BW_STOP in its subheader /// </summary> /// <param name="requestedProtocol"></param> /// <param name="sequenceNumber"></param> private void SendTunnelDataPdu_BWStop(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber) { AUTO_DETECT_REQUEST_TYPE requestType = AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_RELIABLEUDP; RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { requestType = AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_LOSSYUDP; rdpemtServer = rdpemtServerL; } RDP_BW_STOP bwStop = RdpbcgrUtility.GenerateBandwidthMeasureStop(requestType, sequenceNumber); byte[] reqData = rdpbcgrServer.EncodeNetworkDetectionRequest(bwStop, true); List<byte[]> subHdDataList = new List<byte[]>(); subHdDataList.Add(reqData); RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList); rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <summary> /// Expect the Tunnel Create Reponse PDU from server. /// </summary> /// <param name="requestedProtocol">The requested multitransport protocol.</param> /// <returns>The Tunnel Create Response PDU sent by server.</returns> public RDP_TUNNEL_CREATERESPONSE ExpectTunnelCreateResponse(Multitransport_Protocol_value requestedProtocol) { return(rdpemtClients[requestedProtocol].ExpectTunnelCreateResponse(testConfig.timeout)); }
/// <summary> /// Wait for a Tunnel Data PDU with RDP_RTT_RESPONSE and check its sequenceNumber. /// </summary> /// <param name="requestedProtocol">Which tunnel to be used, reliable or lossy</param> /// <param name="sequenceNumber"></param> /// <param name="timeout"></param> private void WaitForAndCheckTunnelDataPdu_RTTResponse(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber, TimeSpan timeout) { bool isReceived = false; TimeSpan leftTime = timeout; DateTime expiratedTime = DateTime.Now + timeout; RDP_RTT_RESPONSE rttResponse = null; RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { rdpemtServer = rdpemtServerL; } while (!isReceived && leftTime.CompareTo(new TimeSpan(0)) > 0) { try { RDP_TUNNEL_DATA tunnelData = rdpemtServer.ExpectTunnelData(leftTime); if (tunnelData != null) { RDP_TUNNEL_SUBHEADER[] SubHeaders = tunnelData.TunnelHeader.SubHeaders; if (SubHeaders != null) { foreach (RDP_TUNNEL_SUBHEADER subHeader in SubHeaders) { if (subHeader.SubHeaderType == RDP_TUNNEL_SUBHEADER_TYPE_Values.TYPE_ID_AUTODETECT_RESPONSE) { NETWORK_DETECTION_RESPONSE detectRsp = rdpbcgrServer.ParseNetworkDetectionResponse(subHeader.SubHeaderData, true); { if (detectRsp.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_RTT_RESPONSE) { rttResponse = (RDP_RTT_RESPONSE)detectRsp; isReceived = true; rttDataStore.responseTime = DateTime.Now; Site.Log.Add(LogEntryKind.Comment, "RequestTime: {0}\tResponseTime: {1}", rttDataStore.responseTime.Ticks, rttDataStore.responseTime.Ticks); } } } } } } } catch (TimeoutException) { Site.Assert.Fail("Timeout when expecting a Tunnel Data PDU with RDP_RTT_RESULTS"); } catch (InvalidOperationException ex) { //break; Site.Log.Add(LogEntryKind.Warning, "Exception thrown out when receiving client PDUs {0}.", ex.Message); } finally { System.Threading.Thread.Sleep(100);//Wait some time for next packet. leftTime = expiratedTime - DateTime.Now; } } if (isReceived) { VerifyTunnelDataPdu_RTTResponse(rttResponse, sequenceNumber); } else { Site.Assert.Fail("Timeout when expecting a Tunnel Data PDU with RDP_RTT_RESULTS"); } }
/// <summary> /// Send a Tunnel Data PDU with RTT Measure Request in its subheader /// </summary> /// <param name="udpTransportMode">Transport Mode: Reliable or Lossy</param> private void SendTunnelDataPdu_RTTMeasureRequest(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber) { AUTO_DETECT_REQUEST_TYPE requestType = AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME; RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { rdpemtServer = rdpemtServerL; } RDP_RTT_REQUEST RTTRequest = RdpbcgrUtility.GenerateRTTMeasureRequest(requestType, sequenceNumber); byte[] reqData = rdpbcgrServer.EncodeNetworkDetectionRequest(RTTRequest, true); List<byte[]> subHdDataList = new List<byte[]>(); subHdDataList.Add(reqData); RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(null, subHdDataList); rttDataStore.requestTime = DateTime.Now; rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <summary> /// Wait for a Tunnel Data PDU with RDP_BW_RESULTS and check its sequenceNumber. /// </summary> /// <param name="requestedProtocol">Which tunnel to be used, reliable or lossy</param> /// <param name="sequenceNumber"></param> /// <param name="timeout"></param> private void WaitForAndCheckTunnelDataPdu_BWResult(Multitransport_Protocol_value requestedProtocol, ushort sequenceNumber, TimeSpan timeout, bool NegiveLossy = false) { bool isReceived = false; TimeSpan leftTime = timeout; DateTime expiratedTime = DateTime.Now + timeout; RDP_BW_RESULTS bwResult = null; RdpemtServer rdpemtServer = rdpemtServerR; if (requestedProtocol == Multitransport_Protocol_value.INITITATE_REQUEST_PROTOCOL_UDPFECL) { rdpemtServer = rdpemtServerL; } while (!isReceived && leftTime.CompareTo(new TimeSpan(0)) > 0) { try { RDP_TUNNEL_DATA tunnelData = rdpemtServer.ExpectTunnelData(leftTime); if (tunnelData != null) { RDP_TUNNEL_SUBHEADER[] SubHeaders = tunnelData.TunnelHeader.SubHeaders; if (SubHeaders != null) { foreach (RDP_TUNNEL_SUBHEADER subHeader in SubHeaders) { if (subHeader.SubHeaderType == RDP_TUNNEL_SUBHEADER_TYPE_Values.TYPE_ID_AUTODETECT_RESPONSE) { NETWORK_DETECTION_RESPONSE detectRsp = rdpbcgrServer.ParseNetworkDetectionResponse(subHeader.SubHeaderData, true); { if (detectRsp.responseType == AUTO_DETECT_RESPONSE_TYPE.RDP_BW_RESULTS_AFTER_CONNECT) { bwResult = (RDP_BW_RESULTS)detectRsp; isReceived = true; bwDataStore.byteCount = bwResult.byteCount; bwDataStore.timeDelta = bwResult.timeDelta; Site.Log.Add(LogEntryKind.Comment, "ByteCount: {0} Bytes\tTimeDelta: {1} Milliseconds", bwDataStore.byteCount, bwDataStore.timeDelta); } } } } } } } catch (TimeoutException) { if (NegiveLossy) { Site.Log.Add(LogEntryKind.Comment, "If the sequenceNumber of RDP_BW_STOP is different from that in RDP_BW_START, Client should not send RDP_BW_RESULTS"); } else { Site.Assert.Fail("Timeout when expecting a Tunnel Data PDU with RDP_BW_RESULTS"); } } catch (InvalidOperationException ex) { //break; Site.Log.Add(LogEntryKind.Warning, "Exception thrown out when receiving client PDUs {0}.", ex.Message); } finally { System.Threading.Thread.Sleep(100);//Wait some time for next packet. leftTime = expiratedTime - DateTime.Now; } } if (isReceived) { VerifyTunnelDataPdu_BWResult(bwResult, sequenceNumber); if (NegiveLossy) { Site.Assert.Fail("If the sequenceNumber of RDP_BW_STOP is different from that in RDP_BW_START, Client should not send RDP_BW_RESULTS"); } } else { if (NegiveLossy) { Site.Log.Add(LogEntryKind.Comment, "If the sequenceNumber of RDP_BW_STOP is different from that in RDP_BW_START, Client should not send RDP_BW_RESULTS"); } else { Site.Assert.Fail("Timeout when expecting a Tunnel Data PDU with RDP_BW_RESULTS"); } } }
/// <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); }