/// <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> /// Parse RDP_NETCHAR_RESULT structure from RDPEMT subheader /// </summary> /// <param name="data">Data of subheader, not include first two bytes of Parse RDP_NETCHAR_RESULT</param> /// <returns></returns> public static RDP_NETCHAR_RESULT ParseRdpNetCharResult(byte[] data) { RDP_NETCHAR_RESULT ncRes = new RDP_NETCHAR_RESULT(); ncRes.sequenceNumber = ParseUInt16(data, 0); ncRes.requestType = (AUTO_DETECT_REQUEST_TYPE)ParseUInt16(data, 2); int index = 4; if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT) { ncRes.bandwidth = ParseUInt32(data, index); index += 4; ncRes.averageRTT = ParseUInt32(data, index); index += 4; } else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT) { ncRes.baseRTT = ParseUInt32(data, index); index += 4; ncRes.averageRTT = ParseUInt32(data, index); index += 4; } else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT) { ncRes.baseRTT = ParseUInt32(data, index); index += 4; ncRes.bandwidth = ParseUInt32(data, index); index += 4; ncRes.averageRTT = ParseUInt32(data, index); index += 4; } return(ncRes); }
/// <summary> /// Encode a RDP_NETCHAR_RESULT structure for subheader, don't encode the first two field /// </summary> /// <param name="bwStop"></param> /// <returns></returns> public static byte[] EncodeNetCharResult(RDP_NETCHAR_RESULT ncRes) { List <byte> bufferList = new List <byte>(); bufferList.AddRange(ToBytes(ncRes.sequenceNumber)); bufferList.AddRange(ToBytes((ushort)ncRes.requestType)); if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT) { bufferList.AddRange(ToBytes(ncRes.bandwidth)); bufferList.AddRange(ToBytes(ncRes.averageRTT)); } else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT) { bufferList.AddRange(ToBytes(ncRes.baseRTT)); bufferList.AddRange(ToBytes(ncRes.averageRTT)); } else if (ncRes.requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT) { bufferList.AddRange(ToBytes(ncRes.baseRTT)); bufferList.AddRange(ToBytes(ncRes.bandwidth)); bufferList.AddRange(ToBytes(ncRes.averageRTT)); } return(bufferList.ToArray()); }
/// <summary> /// Encode NetWork Detection Request /// </summary> /// <param name="sendBuffer">The buffer list to contain the encoded PDU.</param> /// <param name="networkDetectionRequest">The Network Detect Request want to be encoded</param> internal static void EncodeNetworkDetectionRequest(List <byte> sendBuffer, NETWORK_DETECTION_REQUEST networkDetectionRequest, bool isSubHeader = false) { if (!isSubHeader) { EncodeStructure(sendBuffer, networkDetectionRequest.headerLength); EncodeStructure(sendBuffer, (byte)networkDetectionRequest.headerTypeId); } EncodeStructure(sendBuffer, networkDetectionRequest.sequenceNumber); EncodeStructure(sendBuffer, (ushort)networkDetectionRequest.requestType); AUTO_DETECT_REQUEST_TYPE requestType = networkDetectionRequest.requestType; if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_IN_CONNECTTIME || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_RTT_REQUEST_AFTER_CONNECTTIME) { //RDP_RTT_REQUEST } else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_IN_CONNECTTIME || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_AFTER_CONNECTTIME_OR_RELIABLEUDP || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_AFTER_CONNECTTIME_OR_LOSSYUDP) { //RDP_BW_START } else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_PAYLOAD) { //RDP_BW_PAYLOAD RDP_BW_PAYLOAD bwPayload = (RDP_BW_PAYLOAD)networkDetectionRequest; EncodeStructure(sendBuffer, bwPayload.payloadLength); EncodeBytes(sendBuffer, bwPayload.payload); } else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_IN_CONNECTTIME || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_RELIABLEUDP || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_LOSSYUDP) { //RDP_BW_STOP if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_IN_CONNECTTIME) { RDP_BW_STOP bwStop = (RDP_BW_STOP)networkDetectionRequest; EncodeStructure(sendBuffer, bwStop.payloadLength); EncodeBytes(sendBuffer, bwStop.payload); } } else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT || requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT) { //RDP_NETCHAR_RESULT RDP_NETCHAR_RESULT netCharResult = (RDP_NETCHAR_RESULT)networkDetectionRequest; if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT) { EncodeStructure(sendBuffer, netCharResult.bandwidth); EncodeStructure(sendBuffer, netCharResult.averageRTT); } else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_AVERAGERTT) { EncodeStructure(sendBuffer, netCharResult.baseRTT); EncodeStructure(sendBuffer, netCharResult.averageRTT); } else if (requestType == AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT) { EncodeStructure(sendBuffer, netCharResult.baseRTT); EncodeStructure(sendBuffer, netCharResult.bandwidth); EncodeStructure(sendBuffer, netCharResult.averageRTT); } } }
/// <summary> /// Process Auto Detect feature /// </summary> /// <param name="pdu"></param> public override void ProcessSubHeaders(RdpemtBasePDU pdu) { if (pdu == null || pdu.TunnelHeader == null) { return; } if (detectBandwidth) { // if detect device, count bytes bandwidthMeasurePayloadByteCount += ((uint)pdu.TunnelHeader.PayloadLength + pdu.TunnelHeader.HeaderLength); } RDP_TUNNEL_SUBHEADER[] RDPTunnelSubHeaders = pdu.TunnelHeader.SubHeaders; if (RDPTunnelSubHeaders != null) { foreach (RDP_TUNNEL_SUBHEADER RDPTunnelSubHeader in RDPTunnelSubHeaders) { if (RDPTunnelSubHeader.SubHeaderType == RDP_TUNNEL_SUBHEADER_TYPE_Values.TYPE_ID_AUTODETECT_REQUEST) { uint sequenceNumber = (uint)(RDPTunnelSubHeader.SubHeaderData[1] << 8) + RDPTunnelSubHeader.SubHeaderData[0]; uint responseType = (uint)(RDPTunnelSubHeader.SubHeaderData[3] << 8) + RDPTunnelSubHeader.SubHeaderData[2]; if (responseType == (uint)AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_AFTER_CONNECTTIME_OR_LOSSYUDP || responseType == (uint)AUTO_DETECT_REQUEST_TYPE.RDP_BW_START_AFTER_CONNECTTIME_OR_RELIABLEUDP) { // Start bandwidth detect bandwidthMeasureStartTime = DateTime.Now; bandwidthMeasurePayloadByteCount = 0; detectBandwidth = true; } else if (responseType == (uint)AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_LOSSYUDP || responseType == (uint)AUTO_DETECT_REQUEST_TYPE.RDP_BW_STOP_AFTER_CONNECTTIME_OR_RELIABLEUDP) { detectBandwidth = false; TimeSpan duration = DateTime.Now - bandwidthMeasureStartTime; this.timeDelta = (uint)duration.TotalMilliseconds; bwStopSequenceNumber = (ushort)sequenceNumber; // Send RDP_BW_RESULTS if (AutoHandle) { byte[] subHeader = GenerateSubHander_BWResult(); List <byte[]> subHeaders = new List <byte[]>(); subHeaders.Add(subHeader); RDP_TUNNEL_DATA tunnelData = CreateTunnelDataPdu(null, subHeaders, RDP_TUNNEL_SUBHEADER_TYPE_Values.TYPE_ID_AUTODETECT_RESPONSE); this.SendRdpemtPacket(tunnelData); } } else if (responseType == (uint)AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BANDWIDTH_AVERAGERTT || responseType == (uint)AUTO_DETECT_REQUEST_TYPE.RDP_NETCHAR_RESULT_BASERTT_BANDWIDTH_AVERAGERTT) { // Update bandwidth RDP_NETCHAR_RESULT ncRes = RdpemtUtility.ParseRdpNetCharResult(RDPTunnelSubHeader.SubHeaderData); this.bandwidth = ncRes.bandwidth; } } } } }