/// <summary> /// Send an invalid UDP source Packet. /// </summary> /// <param name="udpTransportMode"></param> /// <param name="invalidType"></param> private void SendInvalidUdpSourcePacket(TransportMode udpTransportMode, SourcePacket_InvalidType invalidType) { RdpeudpSocket rdpeudpSocket = rdpeudpSocketR; RdpemtServer rdpemtServer = rdpemtServerR; if (udpTransportMode == TransportMode.Lossy) { rdpeudpSocket = rdpeudpSocketL; rdpemtServer = rdpemtServerL; } if (invalidType == SourcePacket_InvalidType.LargerSourcePayload) { // Change UpStreamMtu of RDPEUDP Socket, so that large data can be sent ushort upstreamMtu = rdpeudpSocket.UUpStreamMtu; rdpeudpSocket.UUpStreamMtu = 2000; byte[] data = new byte[1600]; RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(data, null); rdpemtServer.SendRdpemtPacket(tunnelData); // Change UpStreamMtu to correct value rdpeudpSocket.UUpStreamMtu = upstreamMtu; } }
/// <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> /// Get a valid RDPEUDP packet and send it. /// </summary> /// <param name="udpTransportMode">Transport mode: reliable or lossy.</param> private void SendNextValidUdpPacket(TransportMode udpTransportMode, byte[] data = null) { RdpemtServer rdpemtServer = rdpemtServerR; if (udpTransportMode == TransportMode.Lossy) { rdpemtServer = rdpemtServerL; } if (data == null) data = new byte[1000]; RDP_TUNNEL_DATA tunnelData = rdpemtServer.CreateTunnelDataPdu(data, null); rdpemtServer.SendRdpemtPacket(tunnelData); }
/// <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> /// 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 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> /// 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"); } }