/// <summary>
        /// This action is used to send SEGMENT_INFO_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. </param>
        /// <param name="paddingInConnectionInformation">An array formed by bytes for connection information padding</param>
        /// <param name="segmentInformation">The segment information.</param>
        /// <returns>Return the response message of the SegmentInfoMessage</returns>
        public ResponseMessage SendSegmentInfoMessage(
            byte[] paddingInMessageHeader,
            int pccrrPort,
            byte[] paddingInConnectionInformation,
            SegmentInformation segmentInformation)
        {
            // Convert the struct segmentInformation in adapter to the format in stack
            Content_Information_Data_Structure segmentInformationStack =
                ServerHelper.ConvertTostackForContentInfo(segmentInformation);

            // Create the SEGMENT_INFO_MESSAGE struct defined in stack for SendSegmentInfoMessage method
            SEGMENT_INFO_MESSAGE segmentInfoMessage = this.pchcClient.CreateSegmentInfoMessage(
                pccrrPort,
                segmentInformationStack);

            segmentInfoMessage.MsgHeader.Padding      = paddingInMessageHeader;
            segmentInfoMessage.ConnectionInfo.Padding = paddingInConnectionInformation;

            this.ValidateSegmentInfoMessage(segmentInfoMessage);
            try
            {
                RESPONSE_MESSAGE responseMessageStack = this.pchcClient.SendSegmentInfoMessage(segmentInfoMessage);

                ResponseMessage responseMessage = ServerHelper.ConvertFromStackForResponseMsg(responseMessageStack);

                this.ValidateSegmentInfoResponse(responseMessage);

                return(responseMessage);
            }
            catch (NoRESPONSEMESSAGEException)
            {
                throw new NoResponseMessageException();
            }
        }
        /// <summary>
        /// Offer the block hashes to the hosted cache server.
        /// </summary>
        /// <param name="contentInfo">The content information</param>
        public void OfferHostedCacheContentInfo(Content_Information_Data_Structure contentInfo)
        {
            // It's important to make sure the hosted cache server having the block hash.
            int connectionInfoPort = int.Parse(Site.Properties["PCHC.SegmentInfoMessage.PccrrTransPort"]);

            SEGMENT_INFO_MESSAGE segmentInfoMsgStack = this.pchcClient.CreateSegmentInfoMessage(
                connectionInfoPort,
                contentInfo);

            this.pchcClient.SendSegmentInfoMessage(segmentInfoMsgStack);
        }
        /// <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>
        /// 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.");
        }
        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 SegmentInfoMessage from the Client.
        /// </summary>
        /// <param name="timeout">Waiting for specified timeout to receive the specified request.</param>
        /// <returns>Return the reveived SegmentInfoMessage.</returns>
        public SegmentInfoMessage ExpectSegmentInfoMessage(TimeSpan timeout)
        {
            try
            {
                SEGMENT_INFO_MESSAGE segmentInfoMsgStack = this.pchcServer.ExpectSegmentInfoMessage(
                    this.GetProperty("Environment.SecondContentClient.IPAddress"),
                    timeout);

                this.ValidateSegmentInfoMessage(
                    segmentInfoMsgStack,
                    this.GetProperty("Environment.SecondContentClient.OSVersion"));

                PchcBothRoleCaptureCode.ValidateTransport(this.pchcServer.HttpRequestUri.Scheme);
                this.ValidateTransport(this.pchcServer.HttpRequestMethod);

                SegmentInfoMessage segmentInfoMsg = ClientHelper.ConvertFromStackForSegmentInfoMsg(segmentInfoMsgStack);
                return(segmentInfoMsg);
            }
            catch (NoSEGMENTINFOMESSAGEReceivedException e)
            {
                throw new NoSegmentInfoMessageException(e.Message);
            }
        }
        /// <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}.");
            }
        }
        public void HostedCacheServer_PccrrClient_MessageHeader_CryptoAlgoId(CryptoAlgoId_Values algoId)
        {
            CheckApplicability();

            EventQueue eventQueue = new EventQueue(BaseTestSite);

            eventQueue.Timeout = testConfig.Timeout;

            byte[] content = TestUtility.GenerateRandomArray(ContentInformationUtility.DefaultBlockSize);
            Content_Information_Data_Structure contentInformation = contentInformationUtility.CreateContentInformationV1();

            ProtoVersion protoVersion = new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            };

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Start PCCRR server to be ready to serve content to hosted cache server");

            using (PccrrTestServerV1 pccrrTestServer = new PccrrTestServerV1())
            {
                pccrrTestServer.Start(
                    testConfig.ClientContentRetrievalListenPort,
                    algoId,
                    protoVersion,
                    contentInformation,
                    content,
                    eventQueue);

                PCHCClient pchcClient = new PCHCClient(
                    TransferProtocol.HTTPS,
                    testConfig.HostedCacheServerComputerName,
                    testConfig.HostedCacheServerHTTPSListenPort,
                    PchcConsts.HttpsUrl,
                    testConfig.DomainName,
                    testConfig.UserName,
                    testConfig.UserPassword);

                SEGMENT_INFO_MESSAGE segmentInfoMessage = pchcClient.CreateSegmentInfoMessage(
                    testConfig.ClientContentRetrievalListenPort,
                    contentInformation,
                    0);
                pchcClient.SendSegmentInfoMessage(segmentInfoMessage);

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Offer content block 0 of segment 0 to hosted cache server to 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 == 1);
                }, 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);
            }

            PccrrClient pccrrClient = new PccrrClient(testConfig.HostedCacheServerComputerName, testConfig.HostedCacheServerHTTPListenPort);
            Aes         aes         = PccrrUtitlity.CreateAes(algoId);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Retrieve block 0 of segment 0 from hosted cache server",
                0);
            PccrrGETBLKSRequestPacket pccrrBlkRequest = pccrrClient.CreateMsgGetBlksRequest(
                contentInformation.GetSegmentId(0),
                algoId,
                MsgType_Values.MSG_GETBLKS,
                (uint)0,
                1);

            pccrrClient.SendPacket(
                pccrrBlkRequest,
                testConfig.Timeout);
            PccrrBLKResponsePacket pccrrBlkResponse
                = (PccrrBLKResponsePacket)pccrrClient.ExpectPacket();

            byte[] block = pccrrBlkResponse.MsgBLK.Block;

            if (algoId != CryptoAlgoId_Values.NoEncryption)
            {
                block = PccrrUtitlity.Decrypt(aes, block, contentInformation.segments[0].SegmentSecret, pccrrBlkResponse.MsgBLK.IVBlock);
            }

            BaseTestSite.Assert.IsTrue(
                Enumerable.SequenceEqual(content, block),
                "The retrieved cached data should be the same as server data.");
        }
        public void HostedCacheServer_PccrrClient_MessageHeader_ProtoVerIncompatible()
        {
            CheckApplicability();

            EventQueue eventQueue = new EventQueue(BaseTestSite);

            eventQueue.Timeout = testConfig.Timeout;

            Content_Information_Data_Structure contentInformation = contentInformationUtility.CreateContentInformationV1();

            CryptoAlgoId_Values cryptoAlgoId = CryptoAlgoId_Values.AES_128;
            ProtoVersion        protoVersion = new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            };

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Start PCCRR server to be ready to serve content to hosted cache server");
            using (PccrrTestIncompatibleProtoVerServer pccrrTestServer = new PccrrTestIncompatibleProtoVerServer())
            {
                pccrrTestServer.Start(
                    testConfig.ClientContentRetrievalListenPort,
                    cryptoAlgoId,
                    protoVersion,
                    contentInformation,
                    new byte[0],
                    eventQueue);

                PCHCClient pchcClient = new PCHCClient(
                    TransferProtocol.HTTPS,
                    testConfig.HostedCacheServerComputerName,
                    testConfig.HostedCacheServerHTTPSListenPort,
                    PchcConsts.HttpsUrl,
                    testConfig.DomainName,
                    testConfig.UserName,
                    testConfig.UserPassword);

                SEGMENT_INFO_MESSAGE segmentInfoMessage = pchcClient.CreateSegmentInfoMessage(
                    testConfig.ClientContentRetrievalListenPort,
                    contentInformation,
                    0);
                pchcClient.SendSegmentInfoMessage(segmentInfoMessage);


                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Offer PccrrBLKSResponse with incompatible proto version to 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 == 1);
                }, TimeSpan.MaxValue, TimeSpan.Zero);

                TestUtility.DoUntilSucceed(() => sutControlAdapter.IsLocalCacheExisted(testConfig.HostedCacheServerComputerFQDNOrNetBiosName), testConfig.NegativeTestTimeout, testConfig.RetryInterval);
            }
        }
예제 #10
0
        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.");
            }
        }
예제 #12
0
        public void HostedCacheServer_PchcServer_GetBlocks_SizeOfBlockNotMatch()
        {
            CheckApplicability();

            var contentInformation = contentInformationUtility.CreateContentInformationV1();

            using (var pccrrServer = new PccrrServer(testConfig.ClientContentRetrievalListenPort))
            {
                bool blockRetrieved = false;
                pccrrServer.MessageArrived += new MessageArrivedEventArgs(delegate(IPEndPoint sender, PccrrPacket pccrrPacket)
                {
                    var pccrrGetBlkRequest = (PccrrGETBLKSRequestPacket)pccrrPacket;

                    if (pccrrGetBlkRequest != null)
                    {
                        BaseTestSite.Log.Add(
                            LogEntryKind.Debug,
                            "PCCRR GetBlks request received from hosted cache server. Send malformed Blks response");

                        var pccrrBlocksResponse = pccrrServer.CreateMsgBlkResponse(
                            pccrrGetBlkRequest.MsgGetBLKS.SegmentID,
                            TestUtility.GenerateRandomArray(ContentInformationUtility.DefaultBlockSize),
                            CryptoAlgoId_Values.AES_128,
                            MsgType_Values.MSG_BLK,
                            TestUtility.GenerateRandomArray(16),
                            0,
                            0);
                        var blk                    = pccrrBlocksResponse.MsgBLK;
                        blk.SizeOfBlock            = 0;
                        pccrrBlocksResponse.MsgBLK = blk;
                        pccrrServer.SendPacket(pccrrBlocksResponse);

                        blockRetrieved = true;
                    }
                });
                pccrrServer.StartListening();

                PCHCClient pchcClient = new PCHCClient(
                    TransferProtocol.HTTPS,
                    testConfig.HostedCacheServerComputerName,
                    testConfig.HostedCacheServerHTTPSListenPort,
                    PchcConsts.HttpsUrl,
                    testConfig.DomainName,
                    testConfig.UserName,
                    testConfig.UserPassword);

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Offer block to hosted cache server");

                SEGMENT_INFO_MESSAGE segmentInfoMessage = pchcClient.CreateSegmentInfoMessage(
                    testConfig.ClientContentRetrievalListenPort,
                    contentInformation,
                    0);
                pchcClient.SendSegmentInfoMessage(segmentInfoMessage);

                TestUtility.DoUntilSucceed(() =>
                {
                    return(blockRetrieved);
                }, testConfig.Timeout, testConfig.RetryInterval);
            }

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Try to retrieve the block from hosted cache server");

            PccrrClient pccrrClient = new PccrrClient(
                testConfig.HostedCacheServerComputerName,
                testConfig.HostedCacheServerHTTPListenPort);

            PccrrGETBLKSRequestPacket pccrrBlkRequest = pccrrClient.CreateMsgGetBlksRequest(
                contentInformation.GetSegmentId(0),
                CryptoAlgoId_Values.AES_128,
                MsgType_Values.MSG_GETBLKS,
                0,
                1);

            pccrrClient.SendPacket(
                pccrrBlkRequest,
                testConfig.Timeout);
            PccrrBLKResponsePacket pccrrBlkResponse
                = (PccrrBLKResponsePacket)pccrrClient.ExpectPacket();

            BaseTestSite.Assert.AreEqual <uint>(
                0,
                pccrrBlkResponse.MsgBLK.SizeOfBlock,
                "The server MUST set the SizeOfBlock field to zero if blocks data is not available.");
        }