/// <summary> /// Convert the segmentInforMessageStack struct defined in stack to adapter /// </summary> /// <param name="segmentInforMessageStack">The segmentInforMessageStack message</param> /// <returns>Return the segmentInforMessageStack type defined in adapter</returns> public static SegmentInfoMessage ConvertFromStackForSegmentInfoMsg(SEGMENT_INFO_MESSAGE segmentInforMessageStack) { SegmentInfoMessage segmentInforMessage; segmentInforMessage.ConnectionInfo = ConvertFromStackForConnInfo(segmentInforMessageStack.ConnectionInfo); segmentInforMessage.ContentTag = segmentInforMessageStack.ContentTag; segmentInforMessage.MsgHeader = ConvertFromStackForMsgHeader(segmentInforMessageStack.MsgHeader); segmentInforMessage.SegmentInfo = segmentInforMessageStack.SegmentInfo; return segmentInforMessage; }
/// <summary> /// Transform the SEGMENT_INFO_MESSAGE to a byte array /// </summary> /// <param name="segmentInfoMsg">The SEGMENT_INFO_MESSAGE message</param> /// <returns>The result array</returns> public static byte[] EncodeSegmentInfoMessage(SEGMENT_INFO_MESSAGE segmentInfoMsg) { List<byte> list = new List<byte>(); // Encode MESSAGE_HEADER list.Add(segmentInfoMsg.MsgHeader.MinorVersion); list.Add(segmentInfoMsg.MsgHeader.MajorVersion); list.AddRange(GetBytesFromUshort((ushort)segmentInfoMsg.MsgHeader.MsgType, false)); if (segmentInfoMsg.MsgHeader.Padding == null) { segmentInfoMsg.MsgHeader.Padding = new byte[4]; } list.AddRange(segmentInfoMsg.MsgHeader.Padding); // Encode CONNECTION_INFORMATION list.AddRange(GetBytesFromUint16(segmentInfoMsg.ConnectionInfo.Port, false)); if (segmentInfoMsg.ConnectionInfo.Padding == null) { segmentInfoMsg.ConnectionInfo.Padding = new byte[6]; } list.AddRange(segmentInfoMsg.ConnectionInfo.Padding); // Encode CONTENT_TAG list.AddRange(segmentInfoMsg.ContentTag); // Encode segment infomation. list.AddRange(GetBytesFromUshort(segmentInfoMsg.SegmentInfo.Version, true)); list.AddRange(GetBytesFromUint((uint)segmentInfoMsg.SegmentInfo.dwHashAlgo, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.dwOffsetInFirstSegment, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.dwOffsetInFirstSegment, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.cSegments, true)); for (int i = 0; i < segmentInfoMsg.SegmentInfo.segments.Length; i++) { list.AddRange(GetBytesFromUlong(segmentInfoMsg.SegmentInfo.segments[i].ullOffsetInContent, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.segments[i].cbSegment, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.segments[i].cbBlockSize, true)); list.AddRange(segmentInfoMsg.SegmentInfo.segments[i].SegmentHashOfData); list.AddRange(segmentInfoMsg.SegmentInfo.segments[i].SegmentSecret); } for (int j = 0; j < segmentInfoMsg.SegmentInfo.blocks.Length; j++) { list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.blocks[j].cBlocks, true)); list.AddRange(segmentInfoMsg.SegmentInfo.blocks[j].BlockHashes); } return list.ToArray(); }
/// <summary> /// Transform the SEGMENT_INFO_MESSAGE to a byte array /// </summary> /// <param name="segmentInfoMsg">The SEGMENT_INFO_MESSAGE message</param> /// <returns>The result array</returns> public static byte[] EncodeSegmentInfoMessage(SEGMENT_INFO_MESSAGE segmentInfoMsg) { List <byte> list = new List <byte>(); // Encode MESSAGE_HEADER list.Add(segmentInfoMsg.MsgHeader.MinorVersion); list.Add(segmentInfoMsg.MsgHeader.MajorVersion); list.AddRange(GetBytesFromUshort((ushort)segmentInfoMsg.MsgHeader.MsgType, false)); if (segmentInfoMsg.MsgHeader.Padding == null) { segmentInfoMsg.MsgHeader.Padding = new byte[4]; } list.AddRange(segmentInfoMsg.MsgHeader.Padding); // Encode CONNECTION_INFORMATION list.AddRange(GetBytesFromUint16(segmentInfoMsg.ConnectionInfo.Port, false)); if (segmentInfoMsg.ConnectionInfo.Padding == null) { segmentInfoMsg.ConnectionInfo.Padding = new byte[6]; } list.AddRange(segmentInfoMsg.ConnectionInfo.Padding); // Encode CONTENT_TAG list.AddRange(segmentInfoMsg.ContentTag); // Encode segment infomation. list.AddRange(GetBytesFromUshort(segmentInfoMsg.SegmentInfo.Version, true)); list.AddRange(GetBytesFromUint((uint)segmentInfoMsg.SegmentInfo.dwHashAlgo, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.dwOffsetInFirstSegment, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.dwOffsetInFirstSegment, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.cSegments, true)); for (int i = 0; i < segmentInfoMsg.SegmentInfo.segments.Length; i++) { list.AddRange(GetBytesFromUlong(segmentInfoMsg.SegmentInfo.segments[i].ullOffsetInContent, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.segments[i].cbSegment, true)); list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.segments[i].cbBlockSize, true)); list.AddRange(segmentInfoMsg.SegmentInfo.segments[i].SegmentHashOfData); list.AddRange(segmentInfoMsg.SegmentInfo.segments[i].SegmentSecret); } for (int j = 0; j < segmentInfoMsg.SegmentInfo.blocks.Length; j++) { list.AddRange(GetBytesFromUint(segmentInfoMsg.SegmentInfo.blocks[j].cBlocks, true)); list.AddRange(segmentInfoMsg.SegmentInfo.blocks[j].BlockHashes); } return(list.ToArray()); }
/// <summary> /// Validate the SEGMENT_INFO_MESSAGE related RS /// </summary> /// <param name="segmentInfoMessage">The send message SEGMENT_INFO_MESSAGE</param> private void ValidateSegmentInfoMessage(SEGMENT_INFO_MESSAGE segmentInfoMessage) { Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R87, Validate this by confirm the ContentTag in the send SEGMENT_INFO_MESSAGE is not null. Record SEGMENT_INFO_MESSAGE.ContentTag is not null or not, 0 represents not null and 1 represents null, Record the actual value is {0}", (segmentInfoMessage.ContentTag != null).ToString()); // Capture MS-PCHC R87 this.Site.CaptureRequirementIfIsNotNull( segmentInfoMessage.ContentTag, 87, @"[In SEGMENT_INFO_MESSAGE Request Received] Regardless of whether an INITIAL_OFFER_MESSAGE has previously been received from this client, the hosted cache MUST perform the following actions: The ContentTag is described in the SEGMENT_INFO_MESSAGE request."); }
/// <summary> /// Capture SEGMENT_INFO_MESSAGE message RS /// </summary> /// <param name="segmentInfoMsg">A SEGMENT_INFO_MESSAGE message.</param> /// <param name="platformOsVersion">The operation system.</param> private void ValidateSegmentInfoMessage(SEGMENT_INFO_MESSAGE segmentInfoMsg, string platformOsVersion) { // Validate the MessageHeader in SEGMENT_INFO_MESSAGE. this.ValidateRequestMessageHeader(segmentInfoMsg.MsgHeader); // Validate the connectionInformation in SEGMENT_INFO_MESSAGE. this.ValidateConnectionInformation(segmentInfoMsg.ConnectionInfo); // Valdiate the SegmentInformation in SEGMENT_INFO_MESSAGE. this.ValidateSegmentInformation(segmentInfoMsg.SegmentInfo); // Validate the SegmentInformation about Pccrc this.ValidateSegmentInformationFromPccrc(segmentInfoMsg.SegmentInfo); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R22:The value of PCHCMessageType.SEGMENT_INFO_MESSAGE is {0}.", (int)segmentInfoMsg.MsgHeader.MsgType); // Capture MS-PCHC R22 Site.CaptureRequirementIfAreEqual<PCHCMessageType>( PCHCMessageType.SEGMENT_INFO_MESSAGE, (PCHCMessageType)segmentInfoMsg.MsgHeader.MsgType, 22, @"[In MESSAGE_HEADER][Type (2 bytes):a 16-bit unsigned integer that specifies the message type]The value 0x0002 represent message which is a SEGMENT_INFO_MESSAGE. "); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R36:The segmentInfoMsg is an instance of SEGMENT_INFO_MESSAGE which of cause consists of [MessageHeader, ConnectionInformation, ContentTag, SegmentInformation (variable)]"); // Capture MS-PCHC R36 Site.CaptureRequirement( 36, @"[In SEGMENT_INFO_MESSAGE] A SEGMENT_INFO_MESSAGE consists of the following fields[MessageHeader, ConnectionInformation, ContentTag, SegmentInformation (variable)]."); int sizeofMsgHeader = System.Runtime.InteropServices.Marshal.SizeOf(segmentInfoMsg.MsgHeader); // Capture MS-PCHC R37 and MS-PCHC R129 Site.Assert.AreEqual<int>( 8, sizeofMsgHeader, @"Verify MS-PCHC_R37 and MS-PCHC_R129:The messageHeader is an instance of MessageHeader[8 bytes]."); // Capture MS-PCHC R129 Site.CaptureRequirement( 129, @"[In Request Messages] MessageHeader (8 bytes): A MESSAGE_HEADER structure (section 2.2.1.1)."); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R37:The value of PCHCMessageType.SEGMENT_INFO_MESSAGE is {0}.", (int)segmentInfoMsg.MsgHeader.MsgType); // Capture MS-PCHC R37 Site.CaptureRequirementIfAreEqual<PCHCMessageType>( PCHCMessageType.SEGMENT_INFO_MESSAGE, (PCHCMessageType)segmentInfoMsg.MsgHeader.MsgType, 37, @"[In SEGMENT_INFO_MESSAGE] A SEGMENT_INFO_MESSAGE consists of MessageHeader (8 bytes): A MESSAGE_HEADER structure (section 2.2.1.1), with the Type field set to 0x0002."); int sizeofConnectInfo = System.Runtime.InteropServices.Marshal.SizeOf(segmentInfoMsg.ConnectionInfo); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R38:The segmentInfoMsg Contains a CONNECTION_INFORMATION(8 bytes), but the actual size of the ConnectionInfo is: {0}.", sizeofConnectInfo); Site.CaptureRequirementIfAreEqual<int>( 8, sizeofConnectInfo, 38, @"[In SEGMENT_INFO_MESSAGE] A SEGMENT_INFO_MESSAGE consists of ConnectionInformation (8 bytes): A CONNECTION_INFORMATION structure (section 2.2.1.2)."); // Capture MS-PCHC R39 int size = segmentInfoMsg.ContentTag.Length; Site.CaptureRequirementIfAreEqual<int>( 16, size, 39, @"[In SEGMENT_INFO_MESSAGE] A SEGMENT_INFO_MESSAGE consists of ContentTag (16 bytes): A structure consisting of 16 bytes of opaque data."); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R41:[In SEGMENT_INFO_MESSAGE] [ContentTag ] The tag of SEGMENT_INFO_MESSAGE is added to the information being sent by the client to the hosted cache."); // Capture MS-PCHC R41 // If MS-PCHC_R39 is verified successfully, specify the ContentTag is added in. // So MS-PCHC_R41 is captured directly. Site.CaptureRequirement( 41, @"[In SEGMENT_INFO_MESSAGE] [ContentTag ] The tag of SEGMENT_INFO_MESSAGE is added to the information being sent by the client to the hosted cache."); string contentTag = Encoding.ASCII.GetString(segmentInfoMsg.ContentTag); int endIndex = contentTag.IndexOf('\0'); string contentTagNoSpace = contentTag.Substring(0, endIndex); bool isEqualASC = contentTagNoSpace.Equals("WinINet") || contentTagNoSpace.Equals("WebIO") || contentTagNoSpace.Equals("BITS-4.0"); byte[] contentTagByteValue = new byte[16] { 0x35, 0xDB, 0x04, 0x5D, 0x14, 0x23, 0x45, 0x53, 0xA0, 0x51, 0x0D, 0xC2, 0xE1, 0x5E, 0x6C, 0x4C }; bool isEqualContentTagByteArray = true; for (int i = 0; i < 16; i++) { isEqualContentTagByteArray = isEqualContentTagByteArray && (segmentInfoMsg.ContentTag[i] == contentTagByteValue[i]); } if (platformOsVersion.ToLower().Equals(ClientRoleOSVersion.Win2K8.ToString().ToLower()) || platformOsVersion.ToLower().Equals(ClientRoleOSVersion.Win2K8R2.ToString().ToLower()) || platformOsVersion.ToLower().Equals(ClientRoleOSVersion.Win7.ToString().ToLower()) || platformOsVersion.ToLower().Equals(ClientRoleOSVersion.WinVista.ToString().ToLower())) { // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R124:The segmentInfoMsg Contain a CONTENT_TAG[16 bytes]. The CONTENT_TAG's expected values can be:The ASCII string WinINet.The ASCII string WebIO. The ASCII string BITS-4.0. The binary byte array: 0x35, 0xDB, 0x04, 0x5D, 0x14, 0x23, 0x45, 0x53, 0xA0, 0x51, 0x0D, 0xC2, 0xE1, 0x5E, 0x6C, 0x4C. The actual value is: {0}", contentTagNoSpace); // Capture MS-PCHC R124 Site.CaptureRequirementIfIsTrue( isEqualASC || isEqualContentTagByteArray, 124, @"<3> Section 3.2.1: In the Windows implementation, the values of the content tag can be the following: The ASCII string ""WinINet"". The ASCII string ""WebIO"". The ASCII string ""BITS-4.0"". The binary byte array {0x35, 0xDB, 0x04, 0x5D, 0x14, 0x23, 0x45, 0x53, 0xA0, 0x51, 0x0D, 0xC2, 0xE1, 0x5E, 0x6C, 0x4C}."); } }
/// <summary> /// Send the SEGMENT_INFO_MESSAGE request. /// </summary> /// <param name="segmentInfoMessage">The SEGMENT_INFO_MESSAGE message.</param> /// <returns>The repsonse message RESPONSE_MESSAGE from the hosted cache.</returns> public RESPONSE_MESSAGE SendSegmentInfoMessage(SEGMENT_INFO_MESSAGE segmentInfoMessage) { return this.responseMessage = this.SendByte(EncodeMessage.EncodeSegmentInfoMessage(segmentInfoMessage)); }
/// <summary> /// Send the SEGMENT_INFO_MESSAGE request. /// </summary> /// <param name="segmentInfoMessage">The SEGMENT_INFO_MESSAGE message.</param> /// <returns>The repsonse message RESPONSE_MESSAGE from the hosted cache.</returns> public RESPONSE_MESSAGE SendSegmentInfoMessage(SEGMENT_INFO_MESSAGE segmentInfoMessage) { return(this.responseMessage = this.SendByte(EncodeMessage.EncodeSegmentInfoMessage(segmentInfoMessage))); }