Esempio n. 1
0
        /// <summary>
        /// Computes the <see cref="RouteDistance" /> between the associated <see cref="MsgRouter" />
        /// and a <see cref="LogicalRoute" />.
        /// </summary>
        /// <param name="logicalRoute">The first <see cref="LogicalRoute" />.</param>
        /// <returns>The computed <see cref="RouteDistance" />.</returns>
        internal RouteDistance ComputeDistance(LogicalRoute logicalRoute)
        {
            if (logicalRoute.Handlers != null)
            {
                return(RouteDistance.Process);
            }
            else if (router.RouterEP == null)
            {
                return(RouteDistance.Unknown);
            }

            MsgEP         routerEP    = router.RouterEP;
            MsgEP         targetEP    = logicalRoute.PhysicalRoute.RouterEP;
            PhysicalRoute physical    = logicalRoute.PhysicalRoute;
            int           routerLevel = routerEP.Segments.Length;
            int           targetLevel = targetEP.Segments.Length;
            bool          sameIP      = physical.TcpEP != null && router.TcpEP.Address.Equals(physical.TcpEP.NetEP.Address);

            if (routerEP.IsPhysicalMatch(targetEP))
            {
                // The routes match so we're in the same process.

                return(RouteDistance.Process);
            }

            if (routerLevel == targetLevel)
            {
                // The endpoints are at the same level in the heirarchy.

                switch (routerLevel)
                {
                case 0:

                    // Both routers are at the root level

                    if (sameIP)
                    {
                        return(RouteDistance.Machine);
                    }
                    else
                    {
                        return(RouteDistance.Subnet);
                    }

                case 1:

                    // Must be hub routers on different subnets

                    return(RouteDistance.External);

                case 2:

                    // Both routes are to leaf routers.

                    if (routerEP.IsPhysicalPeer(targetEP))
                    {
                        if (sameIP)
                        {
                            return(RouteDistance.Machine);
                        }
                        else
                        {
                            return(RouteDistance.Subnet);
                        }
                    }

                    // If not peers, then they must be in different datacenters.

                    return(RouteDistance.External);

                default:

                    throw new NotImplementedException();
                }
            }

            // The endpoints are at different levels in the heirarchy.  Normalize
            // these so that higherEP and higherLevel specified the route target
            // that is higher in the heirarchy and lowerEP and lowerLevel the
            // target lower in the heirarchy.

            MsgEP higherEP;
            int   higherLevel;
            MsgEP lowerEP;
            int   lowerLevel;

            if (routerLevel < targetLevel)
            {
                higherEP    = routerEP;
                higherLevel = routerLevel;
                lowerEP     = targetEP;
                lowerLevel  = targetLevel;
            }
            else
            {
                higherEP    = targetEP;
                higherLevel = targetLevel;
                lowerEP     = routerEP;
                lowerLevel  = routerLevel;
            }

            if (higherLevel == 1 && lowerLevel == 2 && higherEP.IsPhysicalDescendant(lowerEP))
            {
                // The higher level endpoint is on a hub and the lower level endpoint is
                // on a router under the hub so they're on the same subnet.

                return(RouteDistance.Subnet);
            }

            // All remaining cases will be considered to be external since
            // they can't be on the same subnet.

            return(RouteDistance.External);
        }