/// <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(); }
/// <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")); }