Esempio n. 1
0
        /// <summary>
        /// Verify members in Error_Context
        /// </summary>
        /// <param name="ctx">Error_Context in Error Response</param>
        /// <param name="uncSharePath">uncSharePath</param>
        /// <param name="sofsHostedNode">ScaleOutFS hosted node</param>
        private void verifyErrorContext(Error_Context ctx, string uncSharePath, string sofsHostedNode)
        {
            #region Verify Error_Context
            BaseTestSite.Assert.AreEqual(
                Error_Id.ERROR_ID_SHARE_REDIRECT,
                ctx.ErrorId,
                "The Error ID should be SMB2_ERROR_ID_SHARE_REDIRECT, actually server returns {0}", ctx.ErrorId);
            BaseTestSite.Assert.IsTrue(
                ctx.ErrorDataLength > 0,
                "The length, in bytes, of the ErrorContextData field should be greater than 0. Actually server returns {0}.", ctx.ErrorDataLength);
            #endregion

            #region Verify Share_Reditect_Error_Context_Response
            Share_Redirect_Error_Context_Response errCtx = ctx.ErrorData.ShareRedirectErrorContextResponse;
            BaseTestSite.Assert.IsTrue(
                errCtx.StructureSize > 0,
                "This field (StructureSize) MUST be set to the size of the structure. Actually server returns {0}.", errCtx.StructureSize);
            BaseTestSite.Assert.AreEqual(
                (uint)3,
                errCtx.NotificationType,
                "This field (NotificationType) MUST be set to 3. Actually server returns {0}.", errCtx.NotificationType);
            byte[] uncSharePathToByte = Encoding.Unicode.GetBytes(uncSharePath);
            BaseTestSite.Assert.AreEqual(
                (uint)uncSharePathToByte.Length,
                errCtx.ResourceNameLength,
                "The length of the share name provided in the ResourceName field, in bytes, should be the length of {0}. Actually server returns {1}.", uncSharePathToByte.Length, errCtx.ResourceNameLength);
            BaseTestSite.Assert.AreEqual(
                0,
                errCtx.Flags,
                "This field (Flags) MUST be set to zero. Actually server returns {0}.", errCtx.Flags);
            BaseTestSite.Assert.AreEqual(
                0,
                errCtx.TargetType,
                "This field (TargetType) MUST be set to zero. Actually server returns {0}.", errCtx.TargetType);
            BaseTestSite.Assert.IsTrue(
                errCtx.IPAddrCount > 0,
                "The number of MOVE_DST_IPADDR structures in the IPAddrMoveList field should be greater than 0. Actually server returns {0}.", errCtx.IPAddrCount);
            IPAddress[] ipv4AddressList = Dns.GetHostEntry(sofsHostedNode).AddressList;
            System.Net.Sockets.AddressFamily addressFamily = ipv4AddressList[0].AddressFamily;

            for (int i = 0; i < errCtx.IPAddrCount; i++)
            {
                Move_Dst_IpAddr dstMoveIpAddr = errCtx.IPAddrMoveList[i];
                BaseTestSite.Assert.AreEqual(
                    (uint)0,
                    dstMoveIpAddr.Reserved,
                    "The server SHOULD set this field to zero, and the client MUST ignore it on receipt. Actually server returns {0}", dstMoveIpAddr.Reserved);
                if (addressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    BaseTestSite.Assert.AreEqual(
                        Move_Dst_IpAddr_Type.MOVE_DST_IPADDR_V4,
                        dstMoveIpAddr.Type,
                        "Type of destination IP address should be MOVE_DST_IPADDR_V4, actually server returns {0}", dstMoveIpAddr.Type);
                    // Check Reserved2 field (offset from 4 to 15) is 0
                    for (int k = 4; k < 16; k++)
                    {
                        BaseTestSite.Assert.IsTrue(
                            dstMoveIpAddr.IPv6Address[k] == 0,
                            "The client MUST set this (Reserved2) to 0.");
                    }
                }
                else if (addressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                {
                    BaseTestSite.Assert.AreEqual(
                        Move_Dst_IpAddr_Type.MOVE_DST_IPADDR_V6,
                        dstMoveIpAddr.Type,
                        "Type of destination IP address should be MOVE_DST_IPADDR_V6, actually server returns {0}", dstMoveIpAddr.Type);
                }
            }

            // Verify all IP addresses for this node are in IPAddrMoveList
            if (addressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                for (int i = 0; i < ipv4AddressList.Length; i++)
                {
                    IPAddress curAddr        = ipv4AddressList[i];
                    bool      isIpAddrInList = false;
                    for (int j = 0; j < errCtx.IPAddrMoveList.Length; j++)
                    {
                        Move_Dst_IpAddr dstMoveIpAddr = errCtx.IPAddrMoveList[j];
                        uint            ipAddr        = BitConverter.ToUInt32(dstMoveIpAddr.IPv6Address, 0);
                        if (ipAddr == (uint)curAddr.Address)
                        {
                            isIpAddrInList = true;
                            break;
                        }
                    }
                    BaseTestSite.Assert.IsTrue(isIpAddrInList, "IP address of sofsHostedNode {0} is not in IPAddrMoveList.", curAddr.ToString());
                }
            }

            string resourceName = Encoding.Unicode.GetString(errCtx.ResourceName, 0, (int)errCtx.ResourceNameLength);
            BaseTestSite.Assert.IsTrue(
                uncSharePath.ToLower().Contains(resourceName.ToLower()),
                "ResourceName should be the same as uncSharePath. Actually server returns {0}.", resourceName);
            #endregion
        }
        /// <summary>
        /// Verify members in Error_Context
        /// </summary>
        /// <param name="ctx">Error_Context in Error Response</param>
        /// <param name="uncSharePath">uncSharePath</param>
        /// <param name="sofsHostedNode">ScaleOutFS hosted node</param>
        private void verifyErrorContext(Error_Context ctx, string uncSharePath, string sofsHostedNode)
        {
            #region Verify Error_Context
            BaseTestSite.Assert.AreEqual(
                Error_Id.ERROR_ID_SHARE_REDIRECT,
                ctx.ErrorId,
                "The Error ID should be SMB2_ERROR_ID_SHARE_REDIRECT, actually server returns {0}", ctx.ErrorId);
            BaseTestSite.Assert.IsTrue(
                ctx.ErrorDataLength > 0,
                "The length, in bytes, of the ErrorContextData field should be greater than 0. Actually server returns {0}.", ctx.ErrorDataLength);
            #endregion

            #region Verify Share_Reditect_Error_Context_Response
            Share_Redirect_Error_Context_Response errCtx = ctx.ErrorData.ShareRedirectErrorContextResponse;
            BaseTestSite.Assert.IsTrue(
                errCtx.StructureSize > 0,
                "This field (StructureSize) MUST be set to the size of the structure. Actually server returns {0}.", errCtx.StructureSize);
            BaseTestSite.Assert.AreEqual(
                (uint)3,
                errCtx.NotificationType,
                "This field (NotificationType) MUST be set to 3. Actually server returns {0}.", errCtx.NotificationType);

            BaseTestSite.Assert.AreEqual(
                0,
                errCtx.Flags,
                "This field (Flags) MUST be set to zero. Actually server returns {0}.", errCtx.Flags);
            BaseTestSite.Assert.AreEqual(
                0,
                errCtx.TargetType,
                "This field (TargetType) MUST be set to zero. Actually server returns {0}.", errCtx.TargetType);
            BaseTestSite.Assert.IsTrue(
                errCtx.IPAddrCount > 0,
                "The number of MOVE_DST_IPADDR structures in the IPAddrMoveList field should be greater than 0. Actually server returns {0}.", errCtx.IPAddrCount);
            IPAddress[] ipv4AddressList = Dns.GetHostAddresses(sofsHostedNode);
            System.Net.Sockets.AddressFamily addressFamily = ipv4AddressList[0].AddressFamily;

            for (int i = 0; i < errCtx.IPAddrCount; i++)
            {
                Move_Dst_IpAddr dstMoveIpAddr = errCtx.IPAddrMoveList[i];
                BaseTestSite.Assert.AreEqual(
                    (uint)0,
                    dstMoveIpAddr.Reserved,
                    "The server SHOULD set this field to zero, and the client MUST ignore it on receipt. Actually server returns {0}", dstMoveIpAddr.Reserved);
                if (addressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    BaseTestSite.Assert.AreEqual(
                        Move_Dst_IpAddr_Type.MOVE_DST_IPADDR_V4,
                        dstMoveIpAddr.Type,
                        "Type of destination IP address should be MOVE_DST_IPADDR_V4, actually server returns {0}", dstMoveIpAddr.Type);
                    // Check Reserved2 field (offset from 4 to 15) is 0
                    for (int k = 4; k < 16; k++)
                    {
                        BaseTestSite.Assert.IsTrue(
                            dstMoveIpAddr.IPv6Address[k] == 0,
                            "The client MUST set this (Reserved2) to 0.");
                    }
                }
                else if (addressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                {
                    BaseTestSite.Assert.AreEqual(
                        Move_Dst_IpAddr_Type.MOVE_DST_IPADDR_V6,
                        dstMoveIpAddr.Type,
                        "Type of destination IP address should be MOVE_DST_IPADDR_V6, actually server returns {0}", dstMoveIpAddr.Type);
                }
            }

            // Verify all IP addresses for this node are in IPAddrMoveList
            if (addressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                for (int i = 0; i < ipv4AddressList.Length; i++)
                {
                    IPAddress curAddr        = ipv4AddressList[i];
                    bool      isIpAddrInList = false;
                    for (int j = 0; j < errCtx.IPAddrMoveList.Length; j++)
                    {
                        Move_Dst_IpAddr dstMoveIpAddr = errCtx.IPAddrMoveList[j];
                        uint            ipAddr        = BitConverter.ToUInt32(dstMoveIpAddr.IPv6Address, 0);
                        if (ipAddr == (uint)curAddr.Address)
                        {
                            isIpAddrInList = true;
                            break;
                        }
                    }
                    BaseTestSite.Assert.IsTrue(isIpAddrInList, "IP address of sofsHostedNode {0} is not in IPAddrMoveList.", curAddr.ToString());
                }
            }

            var resourceName = Encoding.Unicode.GetString(errCtx.ResourceName, 0, (int)errCtx.ResourceNameLength);
            BaseTestSite.Log.Add(LogEntryKind.Debug, $"uncSharePath: {uncSharePath}");
            BaseTestSite.Log.Add(LogEntryKind.Debug, $"ResourceName: {resourceName}");

            BaseTestSite.Assert.IsTrue(
                CompareUNCSharePathAndResourceName(uncSharePath.ToLower(), resourceName.ToLower()),
                "ResourceName should indicate the same share as what uncSharePath indicates. Actually server returns {0}.", resourceName);

            bool CompareUNCSharePathAndResourceName(string uncSharePath, string resourceName)
            {
                var pathRegex = @"\\\\(?<serverName>.+)\\(?<shareName>.+)";
                var regex     = new Regex(pathRegex);

                var uncSharePathMatch = regex.Match(uncSharePath);
                var shareServer       = ExtractServerName(uncSharePathMatch.Groups["serverName"].Value);
                var shareName         = uncSharePathMatch.Groups["shareName"].Value;

                var resourceNameMatch   = regex.Match(resourceName);
                var resourceShareServer = ExtractServerName(resourceNameMatch.Groups["serverName"].Value);
                var resourceShareName   = resourceNameMatch.Groups["shareName"].Value;

                return(shareServer == resourceShareServer && shareName == resourceShareName);

                string ExtractServerName(string matchedGroupValue)
                {
                    // If the matched value is not an FQDN (e.g. computer name or IP address), return it directly.
                    // If the matched value is an FQDN, extract the server name from it.
                    if (!matchedGroupValue.Contains(TestConfig.DomainName, StringComparison.OrdinalIgnoreCase))
                    {
                        return(matchedGroupValue);
                    }
                    else
                    {
                        return(matchedGroupValue.Substring(0, matchedGroupValue.IndexOf(TestConfig.DomainName, StringComparison.OrdinalIgnoreCase) - 1));
                    }
                }
            }

            #endregion
        }