using System; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace MelonVPNCore { public static class DaemonSocketServer { public static void StartServer() { IPHostEntry host = Dns.GetHostEntry("localhost"); IPAddress ipAddress = host.AddressList[0]; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22035); try { Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listener.Bind(localEndPoint); listener.Listen(10); Process currentVpnProcess = null; string lastClientUpdate = Messages.EOF; while (true) { Socket handler = listener.Accept(); string data = null; byte[] bytes = null; while (true) { bytes = new byte[1024]; int bytesRec = handler.Receive(bytes); data += Encoding.ASCII.GetString(bytes, 0, bytesRec); if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break; } if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture)) { lastClientUpdate = data; Client.SendCustomMessage(lastClientUpdate, true); } else if (data == Messages.StatusMsg) { Console.WriteLine("Status requested"); if (currentVpnProcess != null && !currentVpnProcess.HasExited) { Console.WriteLine("Sending response: online"); Client.SendDataMessage(DataMessage.Online, true); Client.SendCustomMessage(lastClientUpdate, true); } else { Console.WriteLine("Sending response: offline"); Client.SendDataMessage(DataMessage.Offline, true); Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); } } else if (data == Messages.StartMsg) { if (currentVpnProcess == null) { Console.WriteLine("Starting VPN"); try { Console.WriteLine("Starting embedded process"); currentVpnProcess = new Process { StartInfo = new ProcessStartInfo("simple-vpn", "client /etc/melon-vpn/client.cfg") }; currentVpnProcess.Exited += delegate { Client.SendDataMessage(DataMessage.Offline, true); currentVpnProcess = null; }; currentVpnProcess.Start(); Console.WriteLine("Sending online reply"); Thread.Sleep(1500); Client.SendDataMessage(DataMessage.Online, true); } catch (Exception e) { Console.WriteLine("There was an error. But I fixed it."); Console.WriteLine("It looked like this: " + e); currentVpnProcess = null; Client.SendDataMessage(DataMessage.Error, true); Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); } } else { Console.WriteLine("VPN already started"); } } else if (data == Messages.StopMsg) { if (currentVpnProcess != null) { Console.WriteLine("Stopping VPN"); try { Console.WriteLine("Stopping embedded process"); currentVpnProcess.Kill(); currentVpnProcess = null; Console.WriteLine("Sending offline reply"); Client.SendDataMessage(DataMessage.Offline, true); Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); } catch (Exception e) { Console.WriteLine("There was an error. But I fixed it."); Console.WriteLine("It looked like this: " + e); currentVpnProcess = null; Client.SendDataMessage(DataMessage.Error, true); Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); } } else { Console.WriteLine("VPN already stopped"); } } Client.SendDataMessage(DataMessage.Blank, true); handler.Shutdown(SocketShutdown.Both); handler.Close(); } } catch (Exception e) { Console.WriteLine(e); } } } }