/// <summary>
        /// Stops a server by relative controller.
        /// </summary>
        /// <param name="controller">A trasmission controller for stop.</param>
        public static void StopServer(BaseServerTransmissionController controller)
        {
            // If transmission has been opening.
            if (controller != null)
            {
                // Disconnect and close pipe.
                try
                {
                    // Disconnects clients.
                    if (controller.PipeServer.IsConnected)
                    {
                        controller.PipeServer.Disconnect();
                    }

                    // Closing pipe.
                    controller.PipeServer.Close();
                }
                catch (Exception ex)
                {
                    // Log error.
                    Console.WriteLine("SERVER STOP FAILED: {0}", ex.Message);
                }

                Console.WriteLine("PIPE CLOSED: {0}", controller.PipeName);
                return;
            }

            Console.WriteLine("META NOT FOUND");
        }
        /// <summary>
        /// Code that will work on server loop when connection will be established.
        /// Recoomended to using as default DNS Handler for message sending.
        /// </summary>
        public static async void ServerToClientAsync(BaseServerTransmissionController controller)
        {
            // Try to get correct controller.
            if (controller is ServerToClientTransmissionController outController)
            {
                try
                {
                    // Log.
                    Console.WriteLine(controller.PipeName + " : SENDING : " + @outController.ProcessingQuery);

                    // Send query to stream.
                    await UniformDataOperator.Binary.IO.StreamHandler.StreamWriterAsync(
                        outController.PipeServer,
                        outController.ProcessingQuery);

                    // Log.
                    Console.WriteLine(controller.PipeName + " : SENT : " + @outController.ProcessingQuery);
                }
                // Catch the Exception that is raised if the pipe is broken or disconnected.
                catch (Exception e)
                {
                    Console.WriteLine("DNS HANDLER ERROR (StC0): {0}", e.Message);
                    return;
                }
            }
            else
            {
                // Log about transmission finish.
                Console.WriteLine("TRANSMISSION ERROR: Try to user invalid controller as output.");
            }

            // Disconnect user if query recived.
            if (controller.PipeServer.IsConnected)
            {
                try
                {
                    controller.PipeServer.Disconnect();
                }
                catch
                {
                    // Exception caused by disconecction on client side.
                }
            }

            // Remove temporal data.
            controller.PipeServer.Dispose();

            // Stop this transmission line.
            controller.SetStoped();

            // Log about transmission finish.
            Console.WriteLine("{0} : TRANSMISSION FINISHED AT {1}",
                              controller.PipeName, DateTime.Now.ToString("HH:mm:ss.fff"));
        }
        /// <summary>
        /// Marks a pipe as expired.
        /// At the next loop tick connections will be disconnected and pipe will be closed.
        /// </summary>
        /// <param name="pipeName">A pipe's name.</param>
        public static void SetExpired(string pipeName)
        {
            // Check meta data existing.
            if (openedServers.ContainsKey(pipeName))
            {
                // Load meta data.
                BaseServerTransmissionController meta = (BaseServerTransmissionController)openedServers[pipeName];

                // Mark it as expired.
                meta.SetExpired();
            }
        }
        /// <summary>
        /// Stops a server by a pipe's name.
        /// </summary>
        /// <param name="pipeName">A pipe's name.</param>
        public static void StopServer(string pipeName)
        {
            // Check meta data existing.
            if (openedServers.ContainsKey(pipeName))
            {
                // Load meta data.
                BaseServerTransmissionController meta = (BaseServerTransmissionController)openedServers[pipeName];

                // Stop server relative to meta data.
                StopServer(meta);

                // Discharge existing in hashtable.
                openedServers.Remove(meta.PipeName);
            }
        }
        /// <summary>
        /// Code that will work on server loop when connection will be established.
        /// Recoomended to using as default DNS Handler for message sending.
        ///
        /// Provide broadcasting to client by useing GetMessage delegate of BroadcastingServerTC controller.
        /// </summary>
        public static async void BroadcastAsync(BaseServerTransmissionController controller)
        {
            // Try to get correct controller.
            if (controller is BroadcastTransmissionController broadcastController)
            {
                // Read until trasmition exits not finished.
                // Avoid an error caused to disconection of client.
                try
                {
                    // Get message
                    byte[] message = broadcastController.GetMessage(broadcastController);

                    // Write message to stream.
                    Console.WriteLine("{0}: Start transmission to client.", controller.PipeName);

                    // Send data to stream.
                    await StreamHandler.StreamWriterAsync(controller.PipeServer, message);
                }
                // Catch the Exception that is raised if the pipe is broken or disconnected.
                catch (Exception e)
                {
                    Console.WriteLine("DNS HANDLER ERROR (StC0): {0}", e.Message);
                    return;
                }
            }
            else
            {
                // Log about transmission finish.
                Console.WriteLine("TRANSMISSION ERROR: Try to user invalid controller for broadcasting.");
            }

            // Disconnect user if query recived.
            if (controller.PipeServer.IsConnected)
            {
                try
                {
                    controller.PipeServer.Disconnect();
                }
                catch
                {
                    // Exception caused by disconecction on client side.
                }
            }

            // Log about transmission finish.
            Console.WriteLine("{0} : TRANSMISSION FINISHED AT {1}",
                              controller.PipeName, DateTime.Now.ToString("HH:mm:ss.fff"));
        }
        /// <summary>
        /// Callback that will react on connection esstablishing.
        /// Will close waiting async operation and call shared delegate with server loop's code.
        /// </summary>
        /// <param name="result"></param>
        public static void ConnectionEstablishedCallbackRetranslator(IAsyncResult result)
        {
            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-us");
            // Load transmission meta data.
            BaseServerTransmissionController meta = (BaseServerTransmissionController)result.AsyncState;

            // Add tread name to simplify debuging.
            Thread.CurrentThread.Name = "ConnectionCallback " + meta.GetHashCode();

            // Stop connection waiting.
            try
            {
                // Trying to close connection if not closed.
                meta.PipeServer.EndWaitForConnection(meta.connectionMarker);
            }
            catch (Exception ex)
            {
                // Log if error caused not just by closed pipe.
                if (!(ex is ObjectDisposedException))
                {
                    Console.WriteLine("CONNECTION ERROR (CECR EWFC): {0} ", ex.Message);
                }
                else
                {
                    // Connection failed. Drop.
                    return;
                }
            }
            finally
            {
                // Unlock searching
                meta.NewConnectionSearchAllowed = true;
            }

            try
            {
                // Wait until connection.
                while (!meta.PipeServer.IsConnected)
                {
                    Thread.Sleep(5);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("CONNECTION ERROR (CECR EWFC 2): {0} {1}", meta.PipeName, ex.Message);
            }

            //Console.WriteLine("\nAsync compleated:{0} {1}\nPipe connected:{2}\n", result.IsCompleted, result.CompletedSynchronously, meta.pipe.IsConnected);

            // Log about success.
            if (meta.PipeServer.IsConnected)
            {
                // Log connection.
                Console.WriteLine("\n{0}: Client connected. Handler: {1}", meta.PipeName, meta.connectionCallback != null ? meta.connectionCallback.Method.Name : "None");

                // Call connection handler.
                meta.connectionCallback?.Invoke(meta);
            }
            else
            {
                Console.WriteLine("\n{0}: Connection waiting was terminated", meta.PipeName);
            }
        }
 /// <summary>
 /// Tries to find opened server transmission metadata in the <see cref="openedServers"/> table.
 /// </summary>
 /// <param name="guid">An unique GUID of the line.</param>
 /// <param name="controller">A found transmission controller.</param>
 /// <returns>A result of the operation.</returns>
 public static bool TryGetServerTransmissionController(string guid, out BaseServerTransmissionController controller)
 {
     controller = openedServers[guid] as BaseServerTransmissionController;
     return(controller != null);
 }
 /// <summary>
 /// Marking pipe as expired.
 /// On the next loop tick connections will be disconnect and pipe will close.
 /// </summary>
 /// <param name="controller">A transmission controller that will expired.</param>
 public static void SetExpired(BaseServerTransmissionController controller)
 {
     // Mark it as expired.
     controller.SetExpired();
 }
Example #9
0
        /// <summary>
        /// Redirect recived query from current server to other.
        /// </summary>
        /// <param name="tc">Server's transmission controller.</param>
        /// <param name="query">Query received from client.</param>
        public static void QueryHandler_DuplexRelay(BaseServerTransmissionController tc, UniformQueries.Query query)
        {
            bool decryptionComplete = false;
            bool decryptionResult   = false;

            Task decryptionOperation = new Task(async delegate()
            {
                // Try to encrypt receved message.
                decryptionResult = await EnctyptionOperatorsHandler.TryToDecryptAsync(
                    query,
                    EnctyptionOperatorsHandler.AsymmetricEO);

                decryptionComplete = true;
            });

            decryptionOperation.Start();

            // Whait for decription completing.
            while (!decryptionComplete)
            {
                Thread.Sleep(5);
            }

            // Loging error to client.
            if (!decryptionResult)
            {
                // Try to get answer in string format.
                SendAnswerViaPP("DUPLEX RELEAY ERROR: Data corrupted." +
                                " Decryption not possible. Relay terminated.", query);
                return;
            }

            // Detect routing target.
            bool relayTargetFound =
                UniformClient.BaseClient.routingTable.
                TryGetRoutingInstruction(query, out Instruction instruction);

            // If instruction not found.
            if (!relayTargetFound)
            {
                // If reley target not found then server will mean that query requested to itself.
                PipesProvider.Handlers.Queries.ProcessingAsync(tc, query);

                //// Log
                //Console.WriteLine("RELAY TARGET NOT FOUND: {q}", query);

                //// DO BACKWARED ERROR INFORMATION.
                //SendAnswer("error=404", UniformQueries.API.DetectQueryParts(query));

                // Drop continue computing.
                return;
            }

            // Open connection.
            TransmissionLine tl = UniformClient.BaseClient.EnqueueDuplexQueryViaPP(
                instruction.routingIP,
                instruction.pipeName,
                query,
                // Delegate that will invoked when relayed server send answer.
                // Redirects the answer to a client.
                delegate(TransmissionLine answerTL, UniformQueries.Query receivedData)
            {
                // Try to get answer in string format.
                SendAnswerViaPP(receivedData, query);
                return;
            });
        }
        /// <summary>
        /// Code that will work on server loop when connection will be established.
        /// Recoomended to using as default DNS Handler for queries reciving.
        /// </summary>
        public static async void ClientToServerAsync(BaseServerTransmissionController controller)
        {
            DateTime sessionTime = DateTime.Now.AddSeconds(5000);

            // Read until trasmition exits not finished.
            while (controller.PipeServer.IsConnected)
            {
                // Open stream reader.
                byte[] binaryQuery;
                #region Reciving message
                // Read data from stream.
                // Avoid an error caused to disconection of client.
                try
                {
                    binaryQuery = await StreamHandler.StreamReaderAsync(controller.PipeServer);
                }
                // Catch the Exception that is raised if the pipe is broken or disconnected.
                catch (Exception e)
                {
                    Console.WriteLine("DNS HANDLER ERROR: {0}", e.Message);
                    return;
                }

                if (DateTime.Compare(sessionTime, DateTime.Now) < 0)
                {
                    Console.WriteLine("Connection terminated cause allowed time has expired.");
                    // Avoid disconnectin error.
                    try
                    {
                        controller.PipeServer.Disconnect();
                    }
                    catch
                    {
                        // Exception caused by disconecction on client side.
                    }

                    return;
                }
                #endregion

                #region Finalizing connection
                // Disconnect user if query recived.
                if (controller.PipeServer.IsConnected)
                {
                    try
                    {
                        controller.PipeServer.Disconnect();
                    }
                    catch
                    {
                        // Exception caused by disconecction on client side.
                    }
                }

                // Remove temporal data.
                controller.PipeServer.Dispose();
                #endregion

                #region Query processing
                // Drop if stream is over.
                if (binaryQuery == null || binaryQuery.Length == 0)
                {
                    //Console.WriteLine("NULL REQUEST AVOIDED. CONNECTION TERMINATED.");
                    break;
                }

                // Decode query from binary data.
                Query query;
                try
                {
                    query = UniformDataOperator.Binary.BinaryHandler.FromByteArray <Query>(binaryQuery);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("DNS HANDLER ERROR (DNS50): DAMAGED DATA : {0}", ex.Message);
                    return;
                }

                // Try to decrypt. In case of fail decryptor returns an entry message.
                await EnctyptionOperatorsHandler.TryToDecryptAsync(
                    query, EnctyptionOperatorsHandler.AsymmetricEO);

                // Log query.
                Console.WriteLine(@"RECIVED QUERY (DNS0): {0}", query);

                // Try to get correct transmisssion controller.
                if (controller is ClientToServerTransmissionController CToSTS)
                {
                    // Redirect handler.
                    CToSTS.queryHandlerCallback?.Invoke(controller, query);
                }
                else
                {
                    // Log error.
                    Console.WriteLine(@"DNS HANDLER ERROR (DNS40):\nQuery processing not posssible.\nTransmission controller not {0}",
                                      typeof(ClientToServerTransmissionController).FullName);
                }
                #endregion
            }

            // Log about transmission finish.
            Console.WriteLine("{0} : TRANSMISSION FINISHED AT {1}",
                              controller.PipeName, DateTime.Now.ToString("HH:mm:ss.fff"));
        }