Ejemplo n.º 1
0
        public static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure();
            log.Info("=== Matrix Master Server Launching ===");

            keyDb = new EncryptionKeyDB("EncryptionKeys");

            manager = new NodeManager("CompiledNodes");
            manager.Initialize();
            manager.LogLoadedModules();

            INodeController controller = manager.InstantiateNodeController();
            if(controller == null)
            {
                log.Error("No INodeController found, the server will not do anything! Exiting...");
                manager.Shutdown();
                Console.ReadLine();
                return;
            }
            hostInterface = new HostInterface(Settings.Default.Port, controller);
            pool = new NodePool(hostInterface);
            hostInterface.Startup();

            nodeLibraryManager = new NodeLibraryManager("CompiledNodes");
            nodeLibraryManager.Initialize();

            host = new NodeHost("CompiledNodes");
            log.Debug("Test download uri: "+host.GetDownloadUrl("MMOController.dll"));

            var controllerRmiType = manager.ControllerRMIType();
            if(controllerRmiType == null)
            {
                log.Error("The node controller does not have an RMI interface! It will not function properly!");
            }
            else
                pool.RegisterNode(new NodeInfo()
                {
                    HostID = new byte[1],
                    Id = 0,
                    RMITypeName = controllerRmiType.FullName,
                    RMIResolvedType = controllerRmiType
                });

            var webServer = NodeWebServer.Create(Settings.Default.HTTPPort);

            Console.WriteLine("Press any key to quit...");
            Console.ReadLine();

            Console.WriteLine("Shutting down...");
            webServer.Stop();
            manager.Shutdown();
            Console.WriteLine("Manager shutdown...");
            hostInterface.Shutdown();
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Create a new Host Interface server.
 /// </summary>
 /// <param name="port">Port to bind to.</param>
 public HostInterface(int port, INodeController controller)
 {
     log.Info("Host server interface launching...");
     this.port = port;
     context = ZmqContext.Create();
     server = context.CreateSocket(SocketType.ROUTER);
     server.TcpKeepalive = TcpKeepaliveBehaviour.Enable;
     this.controller = controller;
     var controllerPortal = new ControllerPortal();
     controllerPortal.SetNodeID(0);
     controller.Initialize(controllerPortal);
     Instance = this;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Process a message for response.
        /// </summary>
        /// <param name="inter">Interface.</param>
        /// <param name="message">Received message.</param>
        public void ProcessMessage(HostInterface inter, byte[] message)
        {
            lastInter = inter;
            if (status == HostStatus.Disconnected)
                return;

            //Reset heartbeat
            heartbeat.Stop ();
            heartbeat.Start ();

            if (status > HostStatus.NoEncryption && message.Length > 1) {
                //Decrypt message
                var decrypt = encryption.Decrypt (message.Skip (1).ToArray ());
                byte[] finalMessage = new byte[1 + decrypt.Length];
                decrypt.CopyTo (finalMessage, 1);
                finalMessage [0] = message [0];
                message = finalMessage;
            }

            if (message [0] != (byte)MessageIdentifier.Heartbeat)
                log.Debug ("Received message: " + Enum.GetName (typeof(MessageIdentifier), message [0]));
            switch ((MessageIdentifier)message [0]) {
            case MessageIdentifier.Heartbeat:
                inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.Heartbeat, null));
                break;
            //Coming from client, this is confirming an identity.
            case MessageIdentifier.SetIdentity:
                if (status != HostStatus.NoIdentity) {
                    log.Debug ("Host already has registered.");
                    break;
                }
                log.Debug ("Identity confirmed, beginning encryption sequence.");
                status = HostStatus.NoEncryption;
                    //Begin encryption exchange
                inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.BeginEncryption, null));
                break;
            //Coming from client, this is the encryption md5.
            case MessageIdentifier.BeginEncryption:
                if (status != HostStatus.NoEncryption) {
                    log.Error ("Unexpected BeginEncryption from host.");
                    break;
                }
                    //Get the encryption key MD5.
                byte[] keymd5 = message.Skip (1).ToArray ();
                log.Debug ("Encryption key confirmation request: " +
                BitConverter.ToString (keymd5).Replace ("-", "").ToLower ());
                AES encrypt = EncryptionKeyDB.Instance.ByHash (keymd5);
                if (encrypt == null) {
                    log.Info ("Key not valid for host, rejecting and disconnecting.");
                    inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.InvalidKey, null));
                    inter.DisconnectHost (hostInfo);
                    status = HostStatus.Disconnected;
                } else {
                    log.Debug ("Host accepted, beginning node sync.");
                    status = HostStatus.SyncNodes;
                    inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.ConfirmEncryption, null));
                    encryption = encrypt;
                }
                break;
            case MessageIdentifier.NodeSync:
                var inputIndex =
                    Serializer.Deserialize<Dictionary<string, byte[]>> (new MemoryStream (message.Skip (1).ToArray ()));
                var syncJob = NodeLibraryManager.Instance.CreateSyncJob (inputIndex);
                if (syncJob == null) {
                    inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.BeginOperation, null));
                    status = HostStatus.LoadingNodes;
                } else {
                    byte[] serializedJob;
                    using (var ms = new MemoryStream ()) {
                        Serializer.Serialize (ms, syncJob);
                        serializedJob = ms.ToArray ();
                        status = HostStatus.SyncNodes;
                    }
                    inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.NodeSync, serializedJob));
                }
                break;
            case MessageIdentifier.GetLibraryURL:
                    //Retreive the library url for the path
                string dataString = Encoding.Unicode.GetString (message, 1, message.Length - 1);
                int reqId = int.Parse (dataString.Split (':') [0]);
                string library = dataString.Split (':') [1];
                var libraryUrl = Encoding.UTF8.GetBytes (reqId + ":" + NodeHost.Instance.GetDownloadUrl (library));
                inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.GetLibraryURL, libraryUrl));
                break;
            case MessageIdentifier.BeginOperation:
                if (status == HostStatus.LoadingNodes) {
                    status = HostStatus.Operating;
                    log.Info ("New host ready for operation.");
                    try {
                        Task.Factory.StartNew (() => inter.Controller.OnHostAdded (hostInfo));
                    } catch (Exception ex) {
                        log.Error ("Error not caught by Controller, " + ex.ToString ());
                    }
                }
                break;
            case MessageIdentifier.NodeVerify:
                int verId = BitConverter.ToInt32 (message, 1);
                NodeInfo info;
                using (MemoryStream ms = new MemoryStream ()) {
                    var inputBytes = message.Skip (1 + sizeof(int)).ToArray ();
                    ms.Write (inputBytes, 0, inputBytes.Length);
                    ms.Position = 0;
                    info = Serializer.Deserialize<NodeInfo> (ms);
                }

                var response = NodePool.Instance.CheckNodeExists (info);
                var respBytes = new byte[sizeof(int) + sizeof(bool)];
                BitConverter.GetBytes (verId).CopyTo (respBytes, 0);
                BitConverter.GetBytes (response).CopyTo (respBytes, sizeof(int));
                inter.SendTo (hostInfo, BuildMessage (MessageIdentifier.NodeVerify, respBytes));
                break;
            case MessageIdentifier.RMIResponse:
                if (status != HostStatus.Operating)
                    return;
                var data = message.Skip (1).ToArray ();
                var rmi = data.Deserialize<NodeRMI> ();
                var destoNode = NodePool.Instance.NodeForId (rmi.SNodeID);
                if (destoNode == null)
                    return;
                if (destoNode.Id == 0)
                    NodePool.Instance.HandleRMIResponse (rmi);
                else {
                    lastInter.RouteRMIResponse (rmi);
                }
                break;
            case MessageIdentifier.ReqNodeList:
                if (status != HostStatus.Operating)
                    return;
                SendEntireNodeList ();
                break;
            case MessageIdentifier.RMIInvoke:
                if (status != HostStatus.Operating)
                    return;
                NodeRMI trmi = message.Skip (1).ToArray ().Deserialize<NodeRMI> ();
                var tdestoNode = NodePool.Instance.NodeForId (trmi.NodeID);
                if (tdestoNode == null) {
                    trmi.SerializeReturnValue (new NodeNotExistException ());
                    lastInter.SendTo (hostInfo, BuildMessage (MessageIdentifier.RMIResponse, trmi.Serialize ()));
                    break;
                }
                lastInter.RouteRMIRequest (trmi, tdestoNode);
                break;
            }
        }