/// <summary> /// Convert the initialOfferMessageStack struct defined in stack to adapter /// </summary> /// <param name="initialOfferMessageStack">The initialOfferMessageStack message</param> /// <returns>Return the initialOfferMessageStack type defined in adapter</returns> public static InitialOfferMessage ConvertFromStackForInitialOfferMsg(INITIAL_OFFER_MESSAGE initialOfferMessageStack) { InitialOfferMessage initialOfferMessage; initialOfferMessage.ConnectionInfo = ConvertFromStackForConnInfo(initialOfferMessageStack.ConnectionInfo); initialOfferMessage.Hash = initialOfferMessageStack.Hash; initialOfferMessage.MsgHeader = ConvertFromStackForMsgHeader(initialOfferMessageStack.MsgHeader); return(initialOfferMessage); }
/// <summary> /// This action is used to send INITIAL_OFFER_MESSAGE request to and receive the /// correspondent Response Message from the hosted cache server. /// </summary> /// <param name="paddingInMessageHeader">An array formed by bytes for message header padding</param> /// <param name="pccrrPort"> /// The port on which MS-PCCRR server-role will be listening if the hosted cache server initiates the /// Peer Content Caching and Retrieval: Retrieval Protocol (PCCRR) framework [MS-PCCRR] as a client-role peer to /// retrieve the missing blocks from the test suite. /// </param> /// <param name="paddingInConnectionInformation">An array formed by bytes for connection information padding</param> /// <param name="hash">Include segment id</param> /// <returns>Return the response message of the InitialOfferMessage</returns> public ResponseMessage SendInitialOfferMessage( byte[] paddingInMessageHeader, int pccrrPort, byte[] paddingInConnectionInformation, byte[] hash) { // Create the INITIAL_OFFER_MESSAGE struct defined in stack for SendInitialOfferMessage method INITIAL_OFFER_MESSAGE initialOfferMessageStack = this.pchcClient.CreateInitialOfferMessage( pccrrPort, hash); initialOfferMessageStack.MsgHeader.Padding = paddingInMessageHeader; initialOfferMessageStack.ConnectionInfo.Padding = paddingInConnectionInformation; try { RESPONSE_MESSAGE responseMessageStack = this.pchcClient.SendInitialOfferMessage(initialOfferMessageStack); if (responseMessageStack.ResponseCode == RESPONSE_CODE.INTERESTED || responseMessageStack.ResponseCode == RESPONSE_CODE.OK) { this.contentUri = this.transportType.ToString().ToLower() + "://" + this.hostedCacheMachineName + ":" + this.httpsListenPort + "/" + PCHCRESOURCE; PchcBothRoleCaptureCode.ValidateTransport(this.transportType.ToString()); this.ValidateTransport(this.pchcClient.HTTPMethod, this.contentUri); this.ValidateServerInitialization(this.httpsListenPort); } // Convert the RESPONSE_MESSAGE to the ResponseMessage struct defined in adapter ResponseMessage responseMessage = ServerHelper.ConvertFromStackForResponseMsg(responseMessageStack); this.ValidateInitialOfferMessageResponse(responseMessage); return(responseMessage); } catch (HttpStatusCode401Exception e) { throw new HttpUnauthenticationException(e.Message); } catch (NoRESPONSEMESSAGEException) { throw new NoResponseMessageException(); } }
public void HostedCacheServer_PchcServer_InitialOffer_SegmentInfoRetrieved() { CheckApplicability(); Content_Information_Data_Structure contentInformation = contentInformationUtility.CreateContentInformationV1(); PCHCClient pchcClient = new PCHCClient( TransferProtocol.HTTPS, testConfig.HostedCacheServerComputerName, testConfig.HostedCacheServerHTTPSListenPort, PchcConsts.HttpsUrl, testConfig.DomainName, testConfig.UserName, testConfig.UserPassword); BaseTestSite.Log.Add( LogEntryKind.Debug, "Send initial offer message to hosted cache server"); INITIAL_OFFER_MESSAGE initialOfferMessage = pchcClient.CreateInitialOfferMessage( testConfig.ClientContentRetrievalListenPort, contentInformation.GetSegmentId(0)); pchcClient.SendInitialOfferMessage(initialOfferMessage); BaseTestSite.Log.Add( LogEntryKind.Debug, "Supply segment info to hosted cache server"); SEGMENT_INFO_MESSAGE segmentInfoMessage = pchcClient.CreateSegmentInfoMessage( testConfig.ClientContentRetrievalListenPort, contentInformation, 0); pchcClient.SendSegmentInfoMessage(segmentInfoMessage); Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pchc.RESPONSE_MESSAGE responseMessage2 = pchcClient.SendInitialOfferMessage(initialOfferMessage); TestClassBase.BaseTestSite.Assert.AreEqual <RESPONSE_CODE>( RESPONSE_CODE.INTERESTED, responseMessage2.ResponseCode, @"The hosted cache MUST specify a response code of 0 if it already has block hash."); }
/// <summary> /// Receive a InitialOfferMessage from the Client. /// </summary> /// <param name="timeout">Waiting for specified timeout to receive the specified request.</param> /// <returns>Return the reveived InitialOfferMessage.</returns> public InitialOfferMessage ExpectInitialOfferMessage(TimeSpan timeout) { try { INITIAL_OFFER_MESSAGE intiailOfferMsgStack = this.pchcServer.ExpectInitialOfferMessage( this.GetProperty("Environment.SecondContentClient.IPAddress"), timeout); this.ValidateInitialOfferMessage(intiailOfferMsgStack); PchcBothRoleCaptureCode.ValidateTransport(this.pchcServer.HttpRequestUri.Scheme); this.ValidateTransport(this.pchcServer.HttpRequestMethod); this.ValidateClientInitialization( this.pchcServer.HttpRequestUri.Host.ToString(), this.pchcServer.HttpRequestUri.Port.ToString(), this.pchcServer.HttpRequestUri.Scheme); InitialOfferMessage intiailOfferMsg = ClientHelper.ConvertFromStackForInitialOfferMsg(intiailOfferMsgStack); return(intiailOfferMsg); } catch (NoINITIALOFFERMESSAGEReceivedException e) { throw new NoInitialOfferMessageException(e.Message); } }
/// <summary> /// Capture the INITIAL_OFFER_MESSAGE message RS /// </summary> /// <param name="initialOfferMsg">A INITIAL_OFFER_MESSAGE message.</param> private void ValidateInitialOfferMessage(INITIAL_OFFER_MESSAGE initialOfferMsg) { // Validate the MessageHeader in INITIAL_OFFER_MESSAGE. this.ValidateRequestMessageHeader(initialOfferMsg.MsgHeader); // Validate the Connectioninformation in INITIAL_OFFER_MESSAGE. this.ValidateConnectionInformation(initialOfferMsg.ConnectionInfo); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R21:The PCHC_MESSAGE_TYPE {0} specifies the INITIAL_OFFER_MESSAGE.", (int)initialOfferMsg.MsgHeader.MsgType); // Capture MS-PCHC R21 Site.CaptureRequirementIfAreEqual <PCHC_MESSAGE_TYPE>( PCHC_MESSAGE_TYPE.INITIAL_OFFER_MESSAGE, initialOfferMsg.MsgHeader.MsgType, 21, @"[In MESSAGE_HEADER] [Type (2 bytes):a 16-bit unsigned integer that specifies the message type]The value 0x0001 represent message which is an INITIAL_OFFER_MESSAGE. "); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R29:The initialOfferMsg is a INITIAL_OFFER_MESSAGE structure which of cause consists of the fields [MessageHeader,ConnectionInformation,Hash]."); // Capture MS-PCHC R29 Site.CaptureRequirement( 29, @"[In INITIAL_OFFER_MESSAGE] An INITIAL_OFFER_MESSAGE consists of the following fields [MessageHeader,ConnectionInformation,Hash]."); int messageHeaderSize = System.Runtime.InteropServices.Marshal.SizeOf(initialOfferMsg.MsgHeader); // Capture MS-PCHC R30 and MS-PCHC R129 Site.Assert.AreEqual <int>( 8, messageHeaderSize, @"Verify MS-PCHC_R30 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_R30:The PCHC_MESSAGE_TYPE {0} specifies the INITIAL_OFFER_MESSAGE.", (int)initialOfferMsg.MsgHeader.MsgType); // Capture MS-PCHC R30 Site.CaptureRequirementIfAreEqual <PCHC_MESSAGE_TYPE>( PCHC_MESSAGE_TYPE.INITIAL_OFFER_MESSAGE, initialOfferMsg.MsgHeader.MsgType, 30, @"[In INITIAL_OFFER_MESSAGE] MessageHeader (8 bytes): A MESSAGE_HEADER structure (section 2.2.1.1), with the Type field set to 0x0001."); // Capture MS-PCHC R33 int sizeofInitialOfferMsg = System.Runtime.InteropServices.Marshal.SizeOf(initialOfferMsg); int sizeofMsgHeader = System.Runtime.InteropServices.Marshal.SizeOf(initialOfferMsg.MsgHeader); int sizeofConnectInfo = System.Runtime.InteropServices.Marshal.SizeOf(initialOfferMsg.ConnectionInfo); // Add the debug information Site.Log.Add( LogEntryKind.Debug, @"Verify MS-PCHC_R33:The hash is a byte array. And initialOfferMsg is received from the client. The total message size is {0}, the sum of the filed sizes that precede the Hash field is messageHeader: {1} + connectInformation: {2} = {3}. And the actual Hash size is {4}", sizeofInitialOfferMsg, sizeofMsgHeader, sizeofConnectInfo, sizeofMsgHeader + sizeofConnectInfo, initialOfferMsg.Hash.Length); Site.CaptureRequirementIfAreEqual <int>( initialOfferMsg.Hash.Length, (sizeofInitialOfferMsg - sizeofMsgHeader - sizeofConnectInfo) * 8, 33, @"[In INITIAL_OFFER_MESSAGE] The size of this field[The Hash field] is calculated as the total message size minus the sum of the field sizes that precede the Hash field."); }
public void HostedCacheServer_BVT_CacheOfferingRetrieval_V1() { CheckApplicability(); EventQueue eventQueue = new EventQueue(BaseTestSite); eventQueue.Timeout = testConfig.Timeout; BaseTestSite.Log.Add( LogEntryKind.Debug, "Trigger hash generation on content server"); byte[] content = contentInformationUtility.RetrieveContentData(); Content_Information_Data_Structure contentInformation = PccrcUtility.ParseContentInformation(contentInformationUtility.RetrieveContentInformation(BranchCacheVersion.V1)); CryptoAlgoId_Values cryptoAlgoId = CryptoAlgoId_Values.AES_128; PccrrClient pccrrClient = new PccrrClient(testConfig.HostedCacheServerComputerName, testConfig.HostedCacheServerHTTPListenPort); for (int i = 0; i < contentInformation.cSegments; ++i) { var pccrrBlkListRequest = pccrrClient.CreateMsgGetBlkListRequest( contentInformation.GetSegmentId(i), new BLOCK_RANGE[] { new BLOCK_RANGE { Index = 0, Count = contentInformation.segments[i].BlockCount } }, cryptoAlgoId, MsgType_Values.MSG_GETBLKLIST); pccrrClient.SendPacket( pccrrBlkListRequest, testConfig.Timeout); var pccrrBlkListResponse = (PccrrBLKLISTResponsePacket)pccrrClient.ExpectPacket(); BaseTestSite.Assert.AreEqual <uint>( 0, pccrrBlkListResponse.MsgBLKLIST.BlockRangeCount, "The server MUST set the BlockRangeCount field to zero if it doesn't have the requested blocks data."); } BaseTestSite.Log.Add( LogEntryKind.Debug, "Retrieve content information from content server"); using (PccrrTestServerV1 pccrrTestServer = new PccrrTestServerV1()) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Start PCCRR server to be ready to serve content to hosted cache server"); pccrrTestServer.Start( testConfig.ClientContentRetrievalListenPort, cryptoAlgoId, contentInformation, content, eventQueue); PCHCClient pchcClient = new PCHCClient( TransferProtocol.HTTPS, testConfig.HostedCacheServerComputerName, testConfig.HostedCacheServerHTTPSListenPort, PchcConsts.HttpsUrl, testConfig.DomainName, testConfig.UserName, testConfig.UserPassword); for (int i = 0; i < contentInformation.cSegments; i++) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Offer content segment {0} to hosted cache server", i); INITIAL_OFFER_MESSAGE initialOfferMessage = pchcClient.CreateInitialOfferMessage( testConfig.ClientContentRetrievalListenPort, contentInformation.GetSegmentId(i)); Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pchc.RESPONSE_MESSAGE responseMessage = pchcClient.SendInitialOfferMessage(initialOfferMessage); TestClassBase.BaseTestSite.Assert.AreEqual <RESPONSE_CODE>( RESPONSE_CODE.INTERESTED, responseMessage.ResponseCode, @"The hosted cache MUST specify a response code of 1 if its list of block hashes associated with the segment is incomplete."); BaseTestSite.Log.Add( LogEntryKind.Debug, "Supply segment info to hosted cache server"); SEGMENT_INFO_MESSAGE segmentInfoMessage = pchcClient.CreateSegmentInfoMessage( testConfig.ClientContentRetrievalListenPort, contentInformation, i); responseMessage = pchcClient.SendSegmentInfoMessage(segmentInfoMessage); TestClassBase.BaseTestSite.Assert.AreEqual <RESPONSE_CODE>( RESPONSE_CODE.OK, responseMessage.ResponseCode, @"The hosted cache MUST send a response code of 0 when SEGMENT_INFO_MESSAGE request received"); BaseTestSite.Log.Add( LogEntryKind.Debug, "Make sure all blocks in segment {0} are retrieved by hosted cache server", i); int blockCount = 0; TestUtility.DoUntilSucceed(delegate() { eventQueue.Expect <MessageArrivedEventArgs>(typeof(PccrrServer).GetEvent("MessageArrived"), delegate(System.Net.IPEndPoint sender, PccrrPacket pccrrPacket) { var pccrrGetBlksRequest = pccrrPacket as PccrrGETBLKSRequestPacket; if (pccrrGetBlksRequest != null) { blockCount++; } }); return(blockCount == contentInformation.segments[i].BlockCount); }, TimeSpan.MaxValue, TimeSpan.Zero); } BaseTestSite.Log.Add( LogEntryKind.Debug, "Wait until cache is available on hosted cache server"); TestUtility.DoUntilSucceed(() => sutControlAdapter.IsLocalCacheExisted(testConfig.HostedCacheServerComputerFQDNOrNetBiosName), testConfig.Timeout, testConfig.RetryInterval); } List <byte> retrievedContent = new List <byte>(); BaseTestSite.Log.Add( LogEntryKind.Debug, "Negotiate PCCRR version"); var pccrrNegotiateRequest = pccrrClient.CreateMsgNegoRequest( new ProtoVersion { MajorVersion = 1, MinorVersion = 0 }, new ProtoVersion { MajorVersion = 1, MinorVersion = ushort.MaxValue }, cryptoAlgoId, MsgType_Values.MSG_NEGO_REQ); pccrrClient.SendPacket( pccrrNegotiateRequest, testConfig.Timeout); var pccrrNegotiateResponse = (PccrrNegoResponsePacket)pccrrClient.ExpectPacket(); if (testConfig.SupportBranchCacheV1) { BaseTestSite.Assert.IsTrue( pccrrNegotiateResponse.MsgNegoResp.MinSupporteProtocolVersion.MajorVersion <= 1 && pccrrNegotiateResponse.MsgNegoResp.MaxSupporteProtocolVersion.MajorVersion >= 1, "SupportedProtocolVersion doesn't match configuration"); } if (testConfig.SupportBranchCacheV2) { BaseTestSite.Assert.IsTrue( pccrrNegotiateResponse.MsgNegoResp.MinSupporteProtocolVersion.MajorVersion <= 2 && pccrrNegotiateResponse.MsgNegoResp.MaxSupporteProtocolVersion.MajorVersion >= 2, "SupportedProtocolVersion doesn't match configuration"); } Aes aes = PccrrUtitlity.CreateAes(cryptoAlgoId); for (int i = 0; i < contentInformation.cSegments; i++) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Retrieve block list for segment {0}", i); var pccrrBlkListRequest = pccrrClient.CreateMsgGetBlkListRequest( contentInformation.GetSegmentId(i), new BLOCK_RANGE[] { new BLOCK_RANGE { Index = 0, Count = contentInformation.segments[i].BlockCount } }, cryptoAlgoId, MsgType_Values.MSG_GETBLKLIST); pccrrClient.SendPacket( pccrrBlkListRequest, testConfig.Timeout); var pccrrBlkListResponse = (PccrrBLKLISTResponsePacket)pccrrClient.ExpectPacket(); BaseTestSite.Assert.AreNotEqual <uint>( 0, pccrrBlkListResponse.MsgBLKLIST.BlockRangeCount, "The server MUST set the BlockRangeCount field to a value greater than zero if it has the requested blocks data."); for (int j = 0; j < contentInformation.segments[i].BlockCount; j++) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Retrieve block {0} for segment {1}", j, i); PccrrGETBLKSRequestPacket pccrrBlkRequest = pccrrClient.CreateMsgGetBlksRequest( contentInformation.GetSegmentId(i), cryptoAlgoId, MsgType_Values.MSG_GETBLKS, (uint)j, 1); pccrrClient.SendPacket( pccrrBlkRequest, testConfig.Timeout); PccrrBLKResponsePacket pccrrBlkResponse = (PccrrBLKResponsePacket)pccrrClient.ExpectPacket(); BaseTestSite.Assert.AreNotEqual <uint>( 0, pccrrBlkResponse.MsgBLK.SizeOfBlock, "The server MUST set the SizeOfBlock field to a value greater than zero if it has the requested blocks data."); byte[] block = pccrrBlkResponse.MsgBLK.Block; if (cryptoAlgoId != CryptoAlgoId_Values.NoEncryption) { block = PccrrUtitlity.Decrypt(aes, block, contentInformation.segments[i].SegmentSecret, pccrrBlkResponse.MsgBLK.IVBlock); } retrievedContent.AddRange(block); } } BaseTestSite.Assert.IsTrue( Enumerable.SequenceEqual(content, retrievedContent), "The retrieved cached data should be the same as server data."); }
public void HostedCacheServer_PchcServer_InitialOffer_ContentRereieved() { CheckApplicability(); EventQueue eventQueue = new EventQueue(BaseTestSite); eventQueue.Timeout = testConfig.Timeout; Content_Information_Data_Structure contentInformation = contentInformationUtility.CreateContentInformationV1(); CryptoAlgoId_Values cryptoAlgoId = CryptoAlgoId_Values.AES_128; using (PccrrTestServerV1 pccrrTestServer = new PccrrTestServerV1()) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Start PCCRR server to be ready to serve content to hosted cache server"); pccrrTestServer.Start( testConfig.ClientContentRetrievalListenPort, cryptoAlgoId, new ProtoVersion { MajorVersion = 1, MinorVersion = 0 }, contentInformation, TestUtility.GenerateRandomArray(ContentInformationUtility.DefaultBlockSize), eventQueue); PCHCClient pchcClient = new PCHCClient( TransferProtocol.HTTPS, testConfig.HostedCacheServerComputerName, testConfig.HostedCacheServerHTTPSListenPort, PchcConsts.HttpsUrl, testConfig.DomainName, testConfig.UserName, testConfig.UserPassword); BaseTestSite.Log.Add( LogEntryKind.Debug, "Send initial offer message to hosted cache server"); SEGMENT_INFO_MESSAGE segmentInfoMessage = pchcClient.CreateSegmentInfoMessage( testConfig.ClientContentRetrievalListenPort, contentInformation, 0); pchcClient.SendSegmentInfoMessage(segmentInfoMessage); BaseTestSite.Log.Add( LogEntryKind.Debug, "Make sure all blocks in segment 0 are retrieved by hosted cache server"); int blockCount = 0; TestUtility.DoUntilSucceed(delegate() { eventQueue.Expect <MessageArrivedEventArgs>(typeof(PccrrServer).GetEvent("MessageArrived"), delegate(System.Net.IPEndPoint sender, PccrrPacket pccrrPacket) { var pccrrGetBlksRequest = pccrrPacket as PccrrGETBLKSRequestPacket; if (pccrrGetBlksRequest != null) { blockCount++; } }); return(blockCount == contentInformation.segments[0].BlockCount); }, TimeSpan.MaxValue, TimeSpan.Zero); BaseTestSite.Log.Add( LogEntryKind.Debug, "Wait until cache is available on hosted cache server"); TestUtility.DoUntilSucceed(() => sutControlAdapter.IsLocalCacheExisted(testConfig.HostedCacheServerComputerFQDNOrNetBiosName), testConfig.Timeout, testConfig.RetryInterval); INITIAL_OFFER_MESSAGE initialOfferMessage = pchcClient.CreateInitialOfferMessage( testConfig.ClientContentRetrievalListenPort, contentInformation.GetSegmentId(0)); Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pchc.RESPONSE_MESSAGE responseMessage2 = pchcClient.SendInitialOfferMessage(initialOfferMessage); TestClassBase.BaseTestSite.Assert.AreEqual <RESPONSE_CODE>( RESPONSE_CODE.INTERESTED, responseMessage2.ResponseCode, @"The hosted cache MUST specify a response code of 0 if it already has block data and block hash."); } }