private void RouteToAsync(Message message, Elastic3D to)
 {
     Task.Factory.StartNew(() =>
     {
         RouteTo(message.Clone(), new Elastic3D(to));
     });
 }
        public static void RouteTo(this Message message, byte ttl, Elastic3D to, ElasticLayout layout, PrivateKey routerKey)
        {
            Payload routes = new Payload.Builder()
                             .Value(TTL, ttl)
                             .Value(TO, to)
                             .Value(LAYOUT, layout)
                             .Value(ROUTER, routerKey.Address.HexAddress)
                             .Value(ROUTERSIG, routerKey.Sign(message.Body.Hash).ToBytes())
                             .Build();

            message.Headers.Set(ROUTES, routes);
        }
Esempio n. 3
0
        public T[] ToArray <T>(Elastic3D coordinates, ElasticLayout layout)
        {
            List <ElasticAddress> resultPeers = new List <ElasticAddress>();

            foreach (var peer in ToArray <ElasticAddress>())
            {
                Elastic3D pos = layout.DefineCoordinates(peer.Address);
                if (coordinates.Contains(pos))
                {
                    resultPeers.Add(peer);
                }
            }

            return(ToArray <T>(resultPeers.ToArray()));
        }
        private void RouteTo(Message message, Elastic3D to)
        {
            // peer lists
            ElasticAddress[] peers = Peers.ToArray <ElasticAddress>(to, message.Layout()).Shuffle();

            // send me if peers contains me
            if (peers.Contains(LocalEndPoint))
            {
                new BConsole.MessageBuilder()
                .Append("(+) Routing message(")
                .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis())
                .Append(") To:")
                .Append(to.Mul() == 0 ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen, to)
                .Append(", Me:")
                .Append(ConsoleColor.DarkCyan, LocalEndPoint.Ellipsis())
                //.WriteLine( $", message={message}");
                .WriteLine();

                SendTo(message, LocalEndPoint);

                return;
            }

            // send message to randomly picked one
            // try next if failed
            foreach (var peer in peers)
            {
                new BConsole.MessageBuilder()
                .Append("(+) Routing message(")
                .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis())
                .Append(") To:")
                .Append(to.Mul() == 0 ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen, to)
                .Append(", Peer:")
                .Append(ConsoleColor.DarkCyan, peer.Ellipsis())
                //.WriteLine($", message={message}");
                .WriteLine();

                if (SendTo(message, peer))
                {
                    break;
                }
            }
        }
 public Elastic3D(Elastic3D other)
 {
     X = other.X;
     Y = other.Y;
     Z = other.Z;
 }
 public bool Contains(Elastic3D pos)
 {
     return((X == 0 || X == pos.X) && (Y == 0 || Y == pos.Y) && (Z == 0 || Z == pos.Z));
 }
 public static byte TimeToLive(this Elastic3D coordinates)
 {
     return((byte)(coordinates.Z > 0 ? 3 : coordinates.Y > 0 ? 2 : coordinates.X > 0 ? 1 : 0));
 }
 public static void RouteTo(this Message message, Elastic3D to, ElasticLayout layout, PrivateKey routerKey)
 {
     RouteTo(message, to.TimeToLive(), to, layout, routerKey);
 }
        private void OnElasticMessage(Message message)
        {
            // routes info
            byte          ttl    = message.TimeToLive();
            Elastic3D     to     = message.To();
            ElasticLayout layout = message.Layout();
            Elastic3D     me     = layout.DefineCoordinates(NodeKey.Address);

            // message router
            Address router = message.Router();

            // router permitted?
            if (!Peers.Exists(router))
            {
                Logger.warning("Unauthorized router!");
                return;
            }

            // verify message
            if (ShouldVerifyRouter && !message.VerifyRouter(router))
            {
                Logger.warning("Router signature not verified!");
                return;
            }

            new BConsole.MessageBuilder()
            .Append("(-) Received ShouldRoute message(")
            .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis())
            .Append(") To:")
            .Append(to.Mul() == 0 ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen, to)
            //.WriteLine($", message={message}");
            .WriteLine();

            // broadcast to all cell
            if (to.Mul() > 0 && ttl == 1)
            {
                ElasticAddress[] peers = Peers.ToArray <ElasticAddress>(to, layout);

                new BConsole.MessageBuilder()
                .Append("(!) Broadcasting message(")
                .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis())
                .Append("), To=")
                .Append(ConsoleColor.DarkGreen, to)
                .Append(", nPeers=")
                .Append(ConsoleColor.DarkGreen, peers.Length)
                //.WriteLine($", message={message}");
                .WriteLine();

                // 해당 좌표의 모든 노드에 전송한다.
                message.RouteTo(0, to, layout, NodeKey);
                SendTo(message, peers);
                return;
            }

            // z-axis must be > 0
            if (to.Z < 1)
            {
                Logger.error($"to.z < 1");
                return;
            }

            // y-axis
            if (ttl == 3)
            {
                for (byte y = 1; y <= layout.Y; y++)
                {
                    to.Y = y;
                    message.RouteTo(2, to, layout, NodeKey);
                    RouteTo(message, to);
                }
            }
            // x-axis
            else if (ttl == 2 && to.Y > 0)
            {
                for (byte x = 1; x <= layout.X; x++)
                {
                    to.X = x;
                    message.RouteTo(1, to, layout, NodeKey);
                    RouteTo(message, to);
                }
            }
        }
        public void SendAll(Message message, byte n)
        {
            // define layout
            ElasticLayout layout = ElasticLayout.DefineLayout(Peers.Count, n);

            if (layout.Mul() <= 1)
            {
                ElasticAddress[] peers = Peers.ToArray <ElasticAddress>();

                new BConsole.MessageBuilder()
                .Append("(!) Broadcasting message(")
                .Append(message.ID.Ellipsis())
                .Append("), To=")
                .Append(ConsoleColor.DarkGreen, layout)
                .Append(", nPeers=")
                .Append(ConsoleColor.DarkGreen, peers.Length)
                //.WriteLine($", message={message}");
                .WriteLine();

                SendTo(message, peers);
                return;
            }

            // this node coordinates
            Elastic3D me = layout.DefineCoordinates(NodeKey.Address);

            // send message to z-axis
            if (layout.Z > 1)
            {
                for (byte z = 1; z <= layout.Z; z++)
                {
                    Elastic3D to = new Elastic3D(0, 0, z);
                    message.RouteTo(3, to, layout, NodeKey);

                    RouteTo(message, to);
                }

                return;
            }

            // send message to y-axis
            if (layout.Y > 1)
            {
                for (byte y = 1; y <= layout.Y; y++)
                {
                    Elastic3D to = new Elastic3D(0, y, 1);
                    message.RouteTo(2, to, layout, NodeKey);

                    RouteTo(message, to);
                }

                return;
            }

            // send message to x-axis
            for (byte x = 1; x <= layout.X; x++)
            {
                Elastic3D to = new Elastic3D(x, 1, 1);
                message.RouteTo(1, to, layout, NodeKey);

                RouteTo(message, to);
            }
        }